10. Les
interfaces graphiques
Ce qui distingue un programme à interface console d’un
programme à interface graphique réside principalement
dans la notion de programmation événementielle:
• Dans le premier cas, c’est le programme
qui pilote l’utilisateur en le sollicitant au moment voulu pour
qu’il fournisse des informations ; le dialogue se fait en mode
texte et de façon séquentielle, dans une fenêtre
nommée "console".
• Dans le second cas, au contraire,
l’utilisateur a l’impression de piloter le programme qui
réagit à des demandes qu’il exprime en
sélectionnant des articles de menu, en cliquant sur des boutons,
en remplissant des boîtes de dialogue.
10.1 AWT et Swing
Java possède plusieurs packages pour utilisation des interfaces
graphiques. Dans ce cours on va discuter Awt et Swing.
Initialement Java ne disposait que du package AWT(Abstract Window
Toolkit) qui repose sur des composants dits
"lourds" et dépendants du système d’exploitation.
Un même composant AWT aura une apparence différente sur
différentes plateformes. La portabilité est
assurée, mais l’apparence peut être
différente à partir du même fichier .class.
Le package Swing propose des composants
dits "légers",
indépendants du système d’exploitation
gérés entièrement par la machine virtuelle , et
dotés de propriétés plus riches que
ceux de AWT.
Les deux packages utilisent des concepts
semblables. Le package Swing utilise une partie des
composant de package AWT.
Component
AWT
Label
AWT
Container
AWT
Panel
AWT
Applet
AWT
JApplet
JComponent
JLabel
JComboBox
AbstractButton
JButton
JToggleButton
JCheckBox
JRadioButton
JMenuItem
JMenu
JCheckBoxMenuItem
JMenuBar
JPanel
JToolBar
JScrollPane
JTabbedPane
JSplitPane
JTextComponent
JTextField
JTextArea
JEditorPane
JList
JTree
JTable
Window
AWT
Frame
AWT
JFrame
Dialog
AWT
JDialog
Jwindow
Fig. 10.1 Les composants Swing
10.2 La classe
JFrame
Pour utiliser une interface graphique l'application doit créer
une fenêtre graphique où on peut mettre des
différents composants.
10.2.1
Création d’une fenêtre
import javax.swing.* ;
public class Window1 {
public static void
main (String args[]){
JFrame wd = new JFrame() ; // constructeur
wd.setSize (250, 100) ; //dimensions (position par
défault sur le moniteur)
wd.setTitle ("graphic window") ;
wd.setVisible (true) ;
}
}
wd.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
//ne rien faire
wd.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
// cacher la fenêtre (comportement par
défaut)
wd.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// détruire l’objet fenêtre
wd.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //
fin à l'application
Dans une autre classe
import javax.swing.* ;
public class MyFrame extends
JFrame{
MyFrame(int
x, int
y, int ln, int ht){
this.setBounds(x, y, ln, ht); //dimensions et position sur
le moniteur
this.setVisible(true);
this. setTitle ("graphic window") ;
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
} |
-------------------------------------------------------
public class Test {
public static void
main(String arg[]){
MyFrame mf = new MyFrame(50,80,200,150);
}
}
10.2.2 Action
sur les caractéristiques d’une fenêtre
import javax.swing.* ;
public class MyFrame extends
JFrame{
MyFrame(int
x, int
y, int ln, int ht){
this.setBounds(x, y, ln, ht);
this.setVisible(true);
this. setTitle ("graphic window") ;
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
-------------------------------------------------------
import java.util.Scanner;
public class Test1 {
public static void main(String arg[]){
Scanner in = new
Scanner(System.in);
MyFrame mf = new
MyFrame(50,80,300,250);
System.out.print("new frame
created, enter to change dimensions");
in.nextLine();
mf.setSize (350, 300) ;
System.out.print("new name:
");
String s = in.nextLine();
mf.setTitle
(s);
System.out.println("boundaries modified ");
mf.setBounds(60,45,350,220); //x, y of
the upper left corner, length, height
System.out.print("new length
");
int ln=
Integer.parseInt(in.nextLine());
System.out.print("new height
");
int height=
Integer.parseInt(in.nextLine());
mf.setSize (ln,height);
System.out.print("enter to
make invisible:");
in.nextLine();
mf.setVisible(false);
System.out.print("enter to
make visible:");
in.nextLine();
mf.setVisible(true);
System.out.print("enter to
finish program");
in.nextLine();
in.close();
System.exit(1);
}
}
10.2.3 Gestion
de la souris – entrée, sortie, clic dans la fenêtre
En Java, tout événement possède ce que
l’on
nomme une source. Il s’agit de l’objet lui ayant
donné naissance : bouton,
article de menu, fenêtre.
Pour traiter un
événement, on a besoin d'un objet, dont la classe
implémente une interface particulière
correspondant à une catégorie
d’événements. On dit que cet objet est un
écouteur (listener) de cette
catégorie d’événements. Chaque
méthode proposée par l’interface correspond
à un
événement de la catégorie. Ainsi, il existe une
catégorie d’événements souris
qu’on peut traiter avec un écouteur de souris.
L'interface correspondant s'appelle MouseListener.
Cette dernière comporte
cinq méthodes correspondant chacune à un
événement particulier : mousePressed(), mouseReleased(), mouseEntered(),
mouseExited() et mouseClicked().
Une classe interne susceptible
d’instancier un objet écouteur de ces différents
événements devra donc redéfinir
tous les méthodes déclarée dans l'interface MouseListener
class MyMouse implements
MouseListener {
public void
mouseClicked (MouseEvent ev) { ..... }
public void
mousePressed (MouseEvent ev) { ..... }
public void
mouseReleased(MouseEvent ev) { ..... }
public void
mouseEntered (MouseEvent ev) { ..... }
public void
mouseExited (MouseEvent ev) { ..... }
// autres
méthodes et champs de la classe
}
import java.awt.event.*;
import javax.swing.* ;
public class MyFrame extends JFrame{
private static final long serialVersionUID = 1L;
JLabel l;
MyFrame(int x, int y, int ln, int ht){
this.setBounds(x, y, ln,
ht);
this.addMouseListener(new
MyMouse());
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
l=new JLabel("to show mouse
events",JLabel.CENTER);
add(l);
this.setVisible(true);
}
public class MyMouse implements MouseListener{
public void
mouseClicked(MouseEvent ev) {
int x =
ev.getX(); int y=ev.getY();
int
xabs=ev.getXOnScreen(); int yabs=ev.getYOnScreen();
l.setText("in: x= "+x+ " y="+y+" ("+xabs+","+yabs+") on screen");
if(ev.getClickCount()==2) l.setText(l.getText()+" double clicked");
}
public void mousePressed
(MouseEvent ev) {}
public void
mouseReleased(MouseEvent ev) {}
public void mouseEntered
(MouseEvent ev) {
l.setText("mouse in");
}
public void mouseExited
(MouseEvent ev) {
l.setText("mouse out");
}
}
}
public class Test {
public static void main(String arg[]){
new
MyFrame(50,80,400,350);
}
}
10.2.4 La
notion d’adaptateur
Java dispose d’une classe particulière MouseAdapter qui
implémente toutes les méthodes de l’interface
MouseListener avec un corps vide.
class MouseAdapter implements
MouseListener {
public void
mouseClicked (MouseEvent ev) {}
public void
mousePressed (MouseEvent ev) {}
public void
mouseReleased(MouseEvent ev) {}
public void
mouseEntered (MouseEvent ev) {}
public void
mouseExited (MouseEvent ev) {}
}
En utilisant la classe à la place de l'interface on ne doit pas
redéfinir des méthodes vides.
public class MyMouse extends
MouseAdapter {
public void
mouseClicked(MouseEvent ev) {
System.out.println("x="+ev.getX() + " y="+ ev.getY());
}
public void
mouseEntered (MouseEvent ev) {
System.out.println("mouse in");
}
public void
mouseExited (MouseEvent ev) {
System.out.println("mouse out");
}
}
10.2.5 La
gestion des événements en général
En particulier, à une catégorie donnée Xxx, on
associera toujours un objet écouteur des
événements (de type XxxEvent), par une méthode
nommée addXxxListener. Chaque fois qu’une catégorie
donnée disposera de plusieurs méthodes, on pourra :
• soit redéfinir toutes les
méthodes de l’interface correspondante XxxListener (la
clause implements XxxListener devant figurer dans l’en-tête
de classe de l’écouteur), certaines méthodes
pouvant avoir un corps vide ;
• soit faire appel à une classe
dérivée d’une classe adaptateur XxxAdapter et ne
fournir que les méthodes qui nous intéressent (lorsque la
catégorie dispose de plusieurs méthodes).
10.3
La classe JButton
10.3.2
Affichage du bouton, gestionnaire de disposition
import javax.swing.* ;
public class MyFrame extends JFrame{
MyFrame(String
name,int x, int y, int ln, int ht){
this.setBounds(x, y, ln, ht);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle(name);
}
}
import javax.swing.*;
public class Test {
public static void
main(String arg[]){
MyFrame mf = new MyFrame("ButtonOne",50,80,200,150);
JButton bt1 = new JButton("butt1");
mf.add(bt1);
// Gestionnaire (Layout)
par défaut
mf.validate();
// validate un conteneur - layout ses composants
}
}
------------------------------------------------------------------
Pour choisir un gestionnaire, il suffit d’appliquer la
méthode setLayout à l’objet contenu de la
fenêtre
import java.awt.*;
import javax.swing.*;
public class Test {
public static void
main(String arg[]){
MyFrame mf =
new
MyFrame("ButtonOne",50,80,200,150);
mf.setLayout(new FlowLayout());
JButton bt1 = new JButton("butt1");
JButton bt2 = new JButton("butt2");
mf.add(bt1);
mf.add(bt2);
mf.validate();
}
}
Disparaître temporairement un bouton par setVisible(false),
Réapparaître par setVisible(true).
10.3.3 Gestion
du bouton avec écouteur
import javax.swing.* ;
public class MyFrame extends JFrame{
MyFrame(String
name,int x, int y, int ln, int ht){
this.setBounds(x, y, ln, ht);
this.setVisible(true);
this.setTitle(name);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
-------------------------
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Test {
static int
cnt1=0,cnt2=0;
public static void
main(String arg[]){
MyFrame mf = new MyFrame("ButtonOne",50,80,200,150);
mf.setLayout(new FlowLayout());
JButton bt1 = new JButton("butt1"); JButton bt2
= new JButton("butt2");
mf.add(bt1);
mf.add(bt2);
bt1.addActionListener(new Bt1());
bt2.addActionListener(new Bt2());
mf.validate();
}
static class Bt1
implements ActionListener{
public void actionPerformed(ActionEvent ev){
System.out.println("butt1: "+ ++cnt1+" times
clicked");
}
}
static class Bt2
implements ActionListener{
public void actionPerformed(ActionEvent ev){
System.out.println("butt2: "+ ++cnt2+" times
clicked");
}
}
}
10.3.4 La
fenêtre écoute les boutons
import java.awt.event.*;
import javax.swing.* ;
public class MyFrame extends JFrame
implements ActionListener{
int cnt1,cnt2;
MyFrame(String
name,int x, int y, int ln, int ht){
this.setBounds(x, y, ln, ht);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle(name);
cnt1=cnt2=0;
}
public void
actionPerformed(ActionEvent ev){
if (ev.getActionCommand().equals("butt1")){
System.out.println("butt1: "+ ++cnt1+" times
clicked");
}
if (ev.getActionCommand().equals("butt2")){
System.out.println("butt2: "+ ++cnt2+" times
clicked");
}
}
}
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Test {
static int
cnt1=0,cnt2=0;
public static void
main(String arg[]){
MyFrame mf = new MyFrame("ButtonOne",50,80,200,150);
mf.setLayout(new FlowLayout());
JButton bt1 = new JButton("butt1");
JButton bt2 = new JButton("butt2");
mf.add(bt1);
mf.add(bt2);
bt1.addActionListener(mf);
bt2.addActionListener(mf);
mf.validate();
}
}
10.3.5 La
méthode getSource()
Elle s'applique à tous les composants
import javax.swing.* ;
public class MyFrame extends JFrame{
MyFrame(String
name,int x, int y, int ln, int ht){
this.setBounds(x, y, ln, ht);
this.setVisible(true);
this.setTitle(name);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
----------------------------------------------------------
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Test1 {
static int
cnt1=0,cnt2=0;
static JButton
bt1,bt2;
static Bt btLs;
public static void
main(String arg[]){
MyFrame mf = new MyFrame("One Listener",50,80,200,150);
mf.setLayout(new FlowLayout());
bt1 = new JButton("butt1");
bt2 = new JButton("butt2");
mf.add(bt1);
mf.add(bt2);
btLs = new Bt();
bt1.addActionListener(btLs);
bt2.addActionListener(btLs);
mf.validate();
}
static class Bt
implements ActionListener{
public void actionPerformed(ActionEvent ev){
if (ev.getSource() == bt1){
System.out.println("butt1: "+
++cnt1+" times clicked");
}
if (ev.getSource() == bt2){
System.out.println("butt2: "+
++cnt2+" times clicked");
}
}
}
}
10.3.6 La
méthode getActionCommand()
Elle s'applique aux composants qui disposent d’une
chaîne de commandes - les boutons, les cases à cocher, les
boutons radio et les options de menu.
static class Bt implements
ActionListener{
public void
actionPerformed(ActionEvent ev){
if (ev.getActionCommand().equals("butt1")){
System.out.println("butt1: "+ ++cnt1+" times
clicked");
}
if (ev.getActionCommand().equals("butt2")){
System.out.println("butt2: "+ ++cnt2+" times
clicked");
}
}
}
10.3.7 Dynamique des
composants
On peut, à tout instant créer un nouveau composant ( add(comp)
), supprimer un
composant ( remove(comp) ). Il faut forcer le gestionnaire de mise en
forme à recalculer les positions des composants dans la
fenêtre, de l’une des façons suivantes:
• en appelant la méthode revalidate()
pour le composant concerné;
• en appelant la méthode validate() (ou
repaint() dans certains cas) pour son conteneur.
import
java.awt.event.*;
import javax.swing.* ;
public class MyFrame extends JFrame{
MyFrame(String name,int x, int y, int ln, int ht){
this.setBounds(x, y, ln, ht);
this.setVisible(true);
this.setTitle(name);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
----------------------------------------------------
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Test {
static JButton bt=null;
static MyFrame mf=null,mfc=null;
public static void main(String arg[]){
mfc = new
MyFrame("ButtonControl",10,80,200,150);
mfc.setLayout(new FlowLayout());
mf = new
MyFrame("Buttons",10,250,200,150);
mf.setLayout(new FlowLayout());
JButton btc1=new JButton("add a
new button");
btc1.addActionListener(new
AdBt());
mfc.add(btc1);
JButton btc2 = new
JButton("remove the button");
btc2.addActionListener(new
RmBt());
mfc.add(btc2);
mfc.validate();
}
static class AdBt implements
ActionListener{
public void
actionPerformed(ActionEvent arg0) {
if(bt == null){
bt = new JButton("added button");
mf.add(bt);
mf.validate(); //or bt.revalidate();
}
}
}
static class RmBt implements
ActionListener{
public void
actionPerformed(ActionEvent arg0) {
if(bt != null){
mf.remove(bt);
mf.setVisible(false);
mf.setVisible(true); // ou mf.repaint();
bt = null;
}
}
}
}
On peut désactiver un
composant (faire en sorte qu’on ne puisse plus agir
sur lui), réactiver un composant désactivé
( setEnabled(true/false) ).
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MyFrame extends JFrame{
MyFrame(String
name){
this.setBounds(200, 250, 250, 200);
this.setVisible(true);
this.setTitle(name);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
//----------------------------------------------------
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Test {
static JButton
bt[];
public static void
main(String arg[]){
MyFrame mf = new MyFrame("activate/desactivate");
bt = new JButton[4];
mf.setLayout(new FlowLayout());
Activ act = new Activ();
bt[0]= new JButton("activate all");
mf.add(bt[0]);
bt[0].addActionListener(act);
for(int i=1;i<bt.length;i++){
bt[i]= new JButton("desactivate "+ i);
mf.add(bt[i]);
bt[i].addActionListener(new Desactiv(i));
}
mf.validate();
}
static class
Desactiv implements ActionListener{
int n;
Desactiv(int n){ this.n = n; }
public void actionPerformed(ActionEvent ev) {
bt[n].setEnabled (false) ;
}
}
static class Activ
implements ActionListener{
public void actionPerformed(ActionEvent ev) {
for(int i = 1; i<bt.length; i++){
bt[i].setEnabled (true) ;
}
}
}
}
10.4
La classe JPanel
Composants intermédiaires qui doivent être contenus
dans
un conteneur, tout en contenant eux-mêmes d’autres
composants.
import
java.awt.event.*;
import
javax.swing.* ;
public
class MyFrame extends JFrame{
MyFrame(String name,int x, int y, int ln, int ht){
this.setBounds(x, y, ln, ht);
this.setVisible(true);
this.setTitle(name);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Test {
static Button bt1,bt2,bt3,bt4;
static JPanel jp1,jp2;
public static void main(String arg[]){
MyFrame mfc=new MyFrame(
"ButtonControl",10,80,200,150);
mfc.setLayout(new
FlowLayout());
jp1 = new JPanel(new
FlowLayout());
jp2 = new JPanel(new
FlowLayout());
jp1.setBackground(Color.yellow);
jp2.setBackground(Color.green);
mfc.add(jp1);
mfc.add(jp2);
bt1 = new Button("show
green");
bt2 = new Button("hide
green");
bt3 = new Button("show
yellow");
bt4 = new Button("hide
yellow");
jp1.add(bt1); jp1.add(bt2);
jp2.add(bt3); jp2.add(bt4);
bt1.addActionListener(new
Show(2));
bt2.addActionListener(new
Hide(2));
bt3.addActionListener(new
Show(1));
bt4.addActionListener(new
Hide(1));
mfc.validate();
}
static class Hide implements ActionListener{
int npan;
Hide(int i){this.npan = i;}
public void
actionPerformed(ActionEvent ev) {
if(npan == 1)jp1.setVisible(false);
else
jp2.setVisible(false);
}
}
static class Show implements ActionListener{
int npan;
Show(int
i){ this.npan =i;}
public void
actionPerformed(ActionEvent ev) {
if(npan == 1)jp1.setVisible(true);
else
jp2.setVisible(true);
}
}
}
10.5 Dessin sur un composant
10.5.1 Dessins
permanents
Pour obtenir que les dessins ne soient modifiés pendant le
réaffichage du composant, il est nécessaire de placer les
instructions de dessin dans une méthode particulière du
composant concerné, nommée paintComponent(). Cette
méthode est automatiquement appelée par Java chaque fois
que le composant a besoin d’être dessiné ou
redessiné.
Il faut aussi appeler explicitement la méthode
paintComponent() de la classe ascendante.
import java.awt.event.*;
import javax.swing.* ;
public class MyFrame extends JFrame{
MyFrame(String
nm,int x, int y, int ln, int ht){
this.setBounds(x, y, ln, ht);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle(nm);
}
}
----------------------------------------------------------------------
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Test {
static JPanel
jp1;
public static void
main(String arg[]){
MyFrame mfc = new MyFrame(
"panel draw",10,80,400,300);
jp1 = new MyPanel();
mfc.add(jp1);
mfc.validate();
}
static class
MyPanel extends JPanel{
public void paintComponent(Graphics g){
super.paintComponent(g) ;
g.drawLine (15, 10, 100, 50) ;
g.drawLine(100, 50, 150, 10);
g.drawOval(60, 150, 50, 80);
g.drawOval(120, 150, 80, 50);
g.drawRect(240, 150, 80, 80);
g.drawOval(240, 150, 80, 80);
}
}
}
10.5.2 La
méthode repaint()
Lorsqu’un composant a besoin d’être
repeint,
Java appelle automatiquement sa méthode paintComponent().
Cependant, il peut être amené à limiter le dessin
à la seule partie
(rectangulaire) du composant qui s’est trouvée
endommagée.
On peut forcer le dessin de l’intégralité du
composant concerné par appel de repaint(), qui est
définit dans la classe de base de tous les composants –
Component.
10.5.3 Dessiner
en directe
Dessiner en direct - au fur et à mesure des actions de
l’utilisateur. Cette démarche est applicable en Java mais
à condition d’accepter que la permanence des dessins ne
soit plus assurée. Pour dessiner à la volée
sur un composant, il est nécessaire :
• D’obtenir un contexte graphique pour ce
composant en utilisant sa méthode getGraphics()
(paintComponent() fournit automatiquement un contexte graphique en
argument).
• D’appliquer les opérations de
dessin à ce contexte graphique comme auparavant.
• De libérer le contexte graphique par
dispose(), afin d’éviter d’encombrer inutilement la
mémoire (paintComponent() réalisait automatiquement cette
libération).
package dessinDirect;
import java.awt.*;
import java.awt.event.*;
import javax.swing.* ;
class MyFrame extends JFrame{
MyFrame () {
setTitle ("Clics traces") ;
setSize (300, 150) ;
setDefaultCloseOperation(EXIT_ON_CLOSE);
pan = new JPanel() ;
add(pan) ;
pan.addMouseListener (new
MyListener(pan)) ;
}
private JPanel pan ;
}
class MyListener extends MouseAdapter {
int xPrev=-1,yPrev=-1;
public MyListener (JPanel pan) {
this.pan = pan ;
}
public void mouseClicked (MouseEvent ev) {
int x = ev.getX(), y = ev.getY() ;
Graphics g = pan.getGraphics() ;
g.drawRect (x, y, 5, 5) ;
if(xPrev>=0)g.drawLine(xPrev,yPrev,x,y);
xPrev=x; yPrev=y;
g.dispose();
}
private JPanel pan ;
}
public class Clics {
public static void main (String args[]){
MyFrame mf = new MyFrame() ;
mf.setVisible(true) ;
}
}
10.6 Gestion des dimensions
10.6.1
Dimensions de l’écran
import javax.swing.* ;
import java.awt.*;
class MyFrame extends JFrame{
MyFrame ()
{
this.setTitle ("Exemple taille fenetre") ;
Toolkit tk = Toolkit.getDefaultToolkit() ;
Dimension dimScr = tk.getScreenSize() ;
this.setSize (dimScr.width/2, dimScr.height/2) ;
this.setVisible(true);
}
}
public class Test {
public static void
main(String arg[]){
MyFrame mf = new MyFrame();
Dimension dimFrame = mf.getSize();
System.out.println(dimFrame.width+":"+dimFrame.height);
}
}
10.6.2 Agir sur
la taille préférentielle d’un composant
composant comp :
comp.setPreferredSize(new Dimension
(width, height)) ; // largeur width, hauteur height
comp.setMinimumSize(new Dimension
(width, height));
comp.setMaximumSize(new Dimension
(width, height));
L’effet dépendra du gestionnaire et du type du composant.
10.7 Les cases à cocher
import java.awt.*;
import java.awt.event.*;
import javax.swing.* ;
public class MyFrame extends JFrame{
MyFrame(String
name){
this.setBounds(10, 10, 150, 120);
this.setVisible(true);
this.setLayout(new FlowLayout());
this.setTitle(name);
this.
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
import java.awt.*;
import java.awt.event.*;
import javax.swing.* ;
public class Test {
static JCheckBox
chck1,chck2;
static Vrfy vr =
new Vrfy();
public static void
main(String arg[]){
MyFrame fm=new MyFrame("Chck");
chck1 = new JCheckBox ("Test",true) ;
JButton bt1 = new JButton("vtfy");
chck2 = new JCheckBox ("Test 1") ;
JButton bt2 = new JButton("cnvrt");
fm.add(chck1);
fm.add(bt1);
fm.add(chck2);
fm.add(bt2);
chck1.addActionListener(vr);
chck2.addItemListener(new Vrfy1());
bt1.addActionListener(vr);
bt2.addActionListener(new Cnvrt());
fm.validate();
}
static class Vrfy
implements ActionListener{
public void actionPerformed(ActionEvent ev){
System.out.println("Echck1:"+chck1.isSelected());
System.out.println("Echck2:"+chck2.isSelected()+"\n");
}
}
static class Vrfy1
implements ItemListener{
public void itemStateChanged (ItemEvent ev){
System.out.println("Ichck1:"+chck1.isSelected());
System.out.println("Ichck2:"+chck2.isSelected()+"\n");
}
}
static class Cnvrt
implements ActionListener{
public void actionPerformed(ActionEvent ev){
if (chck1.isSelected())chck1.setSelected(false);
else chck1.setSelected(true);
if (chck2.isSelected())chck2.setSelected(false);
else chck2.setSelected(true);
}
}
}
10.8 Les boutons radio
JRadioButton bt1 = new JRadioButton
("Test 1") ;
// état non sélectionné
JRadioButton bt2 = new JRadioButton
("Test 2", true) ; // état
sélectionné
Pour la désactivation automatique d’autres boutons radio
d’un même groupe, il faut créer un objet de type
ButtonGroup et associer chacun des boutons voulus à ce groupe
à l’aide de la méthode add():
ButtonGroup grp = new ButtonGroup() ;
grp.add(bt1) ;
grp.add(bt2) ;
10.9 Les étiquettes
JLabel permet d’afficher dans un conteneur un texte (d’une
seule ligne) non modifiable par l’utilisateur, mais que le
programme peut modifier. Son constructeur précise le texte
initial:
JLabel txt = new JLabel ("initial") ;
Le programme peut modifier à tout instant le texte:
txt.setText ("new") ;
10.10 Les champs de texte
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MyFrame extends JFrame
implements ActionListener,FocusListener{
JTextField
tf1,tf2,tf3;
JTextArea ta;
MyFrame(){
this.setSize(300,300);
this.setLayout(new FlowLayout());
tf1 = new JTextField("initial", 10);
tf2 = new JTextField(10);
tf3 = new JTextField(10);
ta = new JTextArea(15,10);
tf2.setEditable(false);
this.add(tf1);
this.add(tf2);
this.add(tf3);
this.add(ta);
tf3.addActionListener(new AdTa());
tf1.addActionListener(this)
;
tf1.addFocusListener(this) ;
this.setVisible(true);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void
actionPerformed(ActionEvent ev){
tf2.setText(tf1.getText());
}
public void
focusGained (FocusEvent e){
System.out.println("Get focus
tf1");
}
public void
focusLost (FocusEvent e){
System.out.println("Lost focus tf1");
}
class AdTa
implements ActionListener{
public void actionPerformed(ActionEvent arg0) {
ta.append(tf3.getText()+"\n");
tf3.setText("");
}
}
public static void
main(String arg[]){
MyFrame mf = new MyFrame();
}
}
10.11 Les classes JList et JComboBox
JListe est un composant qui permet de choisir une ou plusieurs valeurs
dans une liste prédéfinie.
Un objet de JComboBox (drop-down list) est une façon de forcer
l'utilisateur à choisir un seul élément parmi un
groupe de possibilités.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class MyFrame extends JFrame
implements ListSelectionListener,ActionListener,ItemListener{
String s[]=
{"one","two","three","four","five","six"};
JList<String> lst;
JComboBox<String> lstc,lstce;
MyFrame(){
this.setSize(250,200);
this.setLayout(new FlowLayout());
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
lst = new JList<String> (s) ;
lst.addListSelectionListener(this);
lstc = new JComboBox<String>(s);
lstc.addItemListener(this);
lstce = new JComboBox<String>(s);
lstce.addActionListener(this);
lstce.setEditable(true);
this.add(lst);
this.add(lstc);
this.add(lstce);
this.setVisible(true);
}
public void
valueChanged(ListSelectionEvent ev) {
if
(!ev.getValueIsAdjusting()){
//pour eliminer la generation deux fois (press et release)
System.out.print ("items selected:");
int obj[] = lst.getSelectedIndices() ;
for (int i = 0 ; i<obj.length ; i++)
System.out.print (obj[i]+"\t") ;
System.out.println () ;
}
}
public void
actionPerformed (ActionEvent e){
System.out.print ("action select: ") ;
Object obj = lstce.getSelectedItem() ;
System.out.println ((String) obj) ;
}
public void
itemStateChanged (ItemEvent e){
System.out.print ((String) e.getItem()+"\t") ;
if(e.getStateChange()==1)System.out.println ("selected");
else System.out.println ("deselected");
}
public static void
main(String arg[]){
MyFrame mf = new MyFrame();
}
}
10.12 Les boîtes de
dialogue JOptionPane
public static void showMessageDialog(Component parentComponent,
Object message)
throws HeadlessException
public static void showMessageDialog(Component parentComponent,
Object message,
String title,
int messageType) throws HeadlessException
Le parametre messageType détermine l'îcone de mesage:
Paramètre
|
Type
d’icône
|
JOptionPane.ERROR_MESSAGE
|
Erreur
|
JOptionPane.INFORMATION_MESSAGE
|
Information
|
JOptionPane.WARNING_MESSAGE
|
Avertissement
|
JOptionPane.QUESTION_MESSAGE
|
Question
|
JOptionPane.PLAIN_MESSAGE
|
Aucune icône
|
import javax.swing.JOptionPane;
public class Inp {
public static void
main( String[] args ){
String name = "",s_age="";
int age;
name=JOptionPane.showInputDialog("Please enter your name");
for(;;){
s_age=JOptionPane.showInputDialog("How old are You
(between 11 and 89)?");
if(s_age != null){
age=Integer.parseInt(s_age);
if((age>10) &&
(age<90)) break;
}
JOptionPane.showMessageDialog(null, "the age is out
of range",
"error",JOptionPane.ERROR_MESSAGE);
}
String msg = "Hello " + name + " next year,you'll be " + (age + 1);
JOptionPane.showMessageDialog(null, msg);
}
}
10.13 Les menus
Menus déroulants (en anglais "drop-down")-trois classes :
• un objet barre de menus – JMenuBar (il
ne peut y avoir qu'un seul JMenuBar sur un composant donné);
• différents objets menu – JMenu,
qui seront visibles dans la barre de menus;
• pour chaque menu, les différentes
options, de type JMenuItem, qui le constituent.
import java.awt.*;
import java.awt.event.* ;
import javax.swing.* ;
class MyMenu extends JFrame {
JMenuBar mb;
JTextField t;
public MyMenu () {
setTitle ("Menu example") ;
setSize (400, 420) ;
t = new JTextField(3);
setLayout(new FlowLayout());
add(t);
ActionListener al = new ActionListener() {
public void actionPerformed(ActionEvent ev){
t.setText(
(ev.getActionCommand()));
}
};
mb = new JMenuBar() ;
JMenu[] menus = { new JMenu("menu 1"),
new JMenu("menu 2"), new JMenu("menu 3")};
for(int i = 0; i < menus.length; i++)
mb.add(menus[i]);
setJMenuBar(mb);
JMenuItem[] items = {
new JMenuItem("it1"), new JMenuItem("it2")};
for(int i = 0; i < items.length; i++){
items[i].addActionListener(al);
menus[0].add(items[i]);
}
menus[0].addSeparator();
ButtonGroup group = new ButtonGroup() ;
JRadioButtonMenuItem bt[] = {
new JRadioButtonMenuItem("bt1"),
new JRadioButtonMenuItem("bt2")};
bt[0].setToolTipText ("attention -
radio button!") ; // tooltip
for(int i = 0; i < bt.length; i++){
group.add(bt[i]);
bt[i].addActionListener(al);
menus[0].add(bt[i]);
}
menus[0].addSeparator();
JCheckBoxMenuItem cb[]= {new JCheckBoxMenuItem("chk1"),
new JCheckBoxMenuItem("chk2"),new
JCheckBoxMenuItem("chk3")};
for(int i = 0; i < cb.length; i++){
menus[0].add(cb[i]);
cb[i].addActionListener(al);
}
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
}
public static void
main(String arg[]){
new MyMenu();
}
}
Sous options - à la place de JMenuItem
il faut utiliser JMenu
10.14 Les bulles d’aide
voir commentaire tooltip
en 10.13
10.16 Les gestionnaires de mise en
forme
Le gestionnaire de mise en forme (en anglais "Layout manager") est
responsable de la disposition des composants.
10.16.1 Le
gestionnaire BorderLayout
import java.awt.*;
import javax.swing.*;
public class Test {
public static void
main(String a[]){
JFrame fr = new JFrame("Border Layout");
fr.setBounds(80, 50, 300, 200);
fr.setLayout(new BorderLayout());
fr.add("North", new JButton("North"));
fr.add("South",new Button("South"));
fr.add("East",new JButton("East"));
fr.add("West",new JButton("West"));
fr.add("Center",new JButton("Center"));
fr.setVisible(true);
}
}
10.16.2 Le
gestionnaire FlowLayout
import java.awt.*;
import javax.swing.*;
public class Test {
public static void
main(String a[]){
JFrame fr = new JFrame("Flow Layout");
fr.setBounds(80, 50, 500, 200);
fr.setLayout(new FlowLayout());
fr.add(new JButton("First"));
Button b = new Button("Second");
b.setPreferredSize(new Dimension(100,40));
fr.add(b);
fr.add(new Button("Third"));
fr.setVisible(true);
}
}
10.16.3 Le
gestionnaire GridLayout
frame.setLayout (new GridLayout (5,
4)) ; // 5 lignes, 4 colonnes
frame.setLayout (new GridLayout (5,
4, 15, 10)); //intervalle horizontal de 15,
intervalle vertical de 10
import java.awt.*;
import javax.swing.*;
public class Test {
public static void
main(String a[]){
JFrame fr = new JFrame("Flow Layout");
fr.setBounds(80, 50, 500, 200);
fr.setLayout(new GridLayout(2,3));
String labels[] = {"(0,0)","(1,0)","(2,0)",
"(0,1)","(1,1)","(2,1)"};
for(int i=0;i<labels.length;++i)
fr.add(new JButton(labels[i]));
fr.setVisible(true);
}
}
import java.awt.*;
import javax.swing.*;
public class Test {
public static void
main(String a[]){
JFrame fr = new JFrame("Flow Layout");
fr.setBounds(80, 50, 500, 200);
fr.setLayout(new GridLayout(2,3,15,10)); //intervalle horizontal
de 15, intervalle vertical de 10
String labels[] = {"(0,0)","(1,0)","(2,0)",
"(0,1)","(1,1)","(2,1)"};
for(int i=0;i<labels.length;++i)
fr.add(new JButton(labels[i]));
fr.setVisible(true);
}
}
10.16.4 Le
gestionnaire BoxLayout
import javax.swing.* ;
import java.awt.* ;
import java.awt.event.*;
class MyFrame extends JFrame {
JButton bt1
; JLabel label ;
Box bHor ;
JTextField txt ;
public MyFrame ()
{
setTitle ("BoxLayout horizontal") ;
setSize (550, 100) ;
bHor = Box.createHorizontalBox() ;
add(bHor) ;
bt1 = new JButton ("Bouton1") ;
bHor.add (bt1) ;
txt = new JTextField (20) ;
bHor.add (txt) ;
label = new JLabel ("Hello") ;
bHor.add(label) ;
setDefaultCloseOperation(EXIT_ON_CLOSE);;
setVisible(true);
}
}
public class GrL{
public static void
main (String args[]){
MyFrame fm = new MyFrame() ;
}
}
10.16.5 Le
gestionnaire GridBagLayout
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GridBag extends JFrame {
GridBagLayout
gridBagLayout = new GridBagLayout();
GridBag(){
setTitle("GridBagLayout");
setLayout(gridBagLayout);
setSize(300,200);
JButton gridBagButtons[] = new JButton[9];
for(int i=0;i<9;++i) gridBagButtons[i] = new JButton("Button"+i);
int gridx[] = {0,1,2,0,2,0,1,1,0};
int gridy[] = {0,0,0,1,1,2,2,3,4};
int gridwidth[] = {1,1,1,2,1,1,1,2,3};
int gridheight[] = {1,1,1,1,2,2,1,1,1};
GridBagConstraints gridBagConstraints[] = new GridBagConstraints[9];
for(int i=0;i<9;++i) {
gridBagConstraints[i] = new GridBagConstraints();
gridBagConstraints[i].fill=GridBagConstraints.BOTH;
gridBagConstraints[i].gridx=gridx[i];
gridBagConstraints[i].gridy=gridy[i];
gridBagConstraints[i].gridwidth=gridwidth[i];
gridBagConstraints[i].gridheight=gridheight[i];
gridBagLayout.setConstraints(gridBagButtons[i],gridBagConstraints[i]);
add(gridBagButtons[i]);
}
setDefaultCloseOperation(EXIT_ON_CLOSE);;
}
public static void
main(String arg[]){
GridBag gb = new GridBag();
gb.setVisible(true);
}
}
10.16.7 Mise en
forme sans gestionnaire (positionnement absolu)
l'utilisateur choisit la place et les dimensions des composants a la
main. Pour le faire il faut suivre les pas suivants:
• Réglez gestionnaire du conteneur
à null en appelant setLayout (null);
• Pour chaque composant dans le conteneur
appelez la méthode setBounds();
Button bt = new Button("bt");
bt.setBounds(x, y, width,
height); //x et y sont coordonées du coin supérieur
gauche
• Faire recalculer le conteneur avec la
méthode validate() correspondant.
La création de conteneurs avec des composants à
positionnement absolu peuvent causer des problèmes si la
fenêtre contenant le conteneur est redimensionnée.
10.17 Textes et graphiques
10.17.1 La
classe FontMetrics
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Disposition
extends JFrame{
MyPanel pan;
public
Disposition(){
setTitle ("Disposition") ;
setSize (180, 120) ;
pan = new MyPanel();
add(pan);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
class MyPanel
extends JPanel{
public void paintComponent(Graphics g){
super.paintComponent(g) ;
int x=10,y=10;
String s[] = {"one ","two ","three "};
FontMetrics fm = g.getFontMetrics();
for(int i =0;i<s.length;i++){
g.drawString( s[i],x, y);
x+=fm.stringWidth(s[i]);
}
x=10;
for(int i =0;i<s.length;i++){
y+=fm.getHeight();
g.drawString( s[i],x, y);
}
}
}
public static void
main(String arg[]){
Disposition d = new Disposition();
}
}
10.17.2 Choix
de police de caractères
En Java, une police se définit par:
• un nom de famille de police (Helvetica, Arial,
Times Roman ...) ;
• un style: romain (normal), gras ou italique ;
• une taille, exprimée en "points
typographiques" (et non en pixels).
import javax.swing.* ;
import java.awt.* ;
import java.awt.event.*;
class Police extends JFrame {
JPanel pan;
Police (){
setTitle ("Fonts") ;
setSize (220, 150) ;
pan = new MyPanel() ;
add(pan) ;
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
class MyPanel
extends JPanel {
public void paintComponent(Graphics g){
super.paintComponent(g) ;
FontMetrics fm = g.getFontMetrics() ;
String fnts[] =
GraphicsEnvironment.getLocalGraphicsEnvironment()
.getAvailableFontFamilyNames() ;
int x=10, y=20;
g.drawString("by default:
"+g.getFont().getFontName()+
g.getFont().getSize(),x,y);
//defaut police
y+=fm.getHeight()+10;
Font fn = new Font ("Serif", Font.BOLD+Font.ITALIC,
20) ; //police logique
g.setFont(fn);
g.drawString (fn.getFontName()+"20", x, y) ;
fn = new Font(fnts[3],Font.PLAIN,
25);
//police phisique
y+=fm.getHeight()+10;
g.setFont(fn);
g.drawString (fn.getFontName()+" 25", x, y) ;
}
}
public static void
main(String arg[]){
Police d = new Police();
}
}
Remarque :
- La couleur du texte n’est pas définie par la fonte
elle-même, mais par la couleur d’avant plan courante du
composant
10.17.3 Les
objets couleur
Color.black, Color.blue, Color.cyan, Color.darkGray, Color.gray,
Color.green, Color.lightGray, Color.magenta, Color.orange, Color.pink,
Color.red, Color.white, Color.yellow
class MyPanel extends JPanel {
public void paintComponent(Graphics g){
setForeground(Color.blue);
//couleur avant plant
…
setBackground(Color.yellow);
//couleur fond
…
setForeground(new
Color(200,80,90));
//couleur construit - RGB, bytes
…
g.setColor(Color.magenta);
//couleur avant plant
}
}
Remarque :
- La couleur réellement obtenue sur l'écran
dépendra du système. En effet, vous obtiendrez la couleur
la plus proche compatible avec l'environnement. Dans le cas où
seules 16 couleurs sont disponibles, la différence entre la
couleur demandée et celle effectivement obtenue pourra se
révéler importante
- Il est possible, à partir d’une couleur
donnée c d’obtenir une même couleur plus brillante
par c.brighter() ou plus sombre par c.darker()
10.17.5
Affichage d’images
• GIF (Graphical Interchange Format) : 256
couleurs ;
• JPEG (Joint Photograhic Expert Group) : plus
de 16 millions de couleurs (ce format compressé est plus long
à traiter que le précédent).
• PNG
ImageIcon imIc = new ImageIcon (...)
; // chargement de l’image dans imIc
Image im = imIc.getImage() ;
// im contient
la référence à l’objet de type Image
correspondant
…
g.drawImage (im, x, y, null)
; // x et y
sont les coordonnée de coin gauche supérieur d'image
drawImage(Image img, int x, int y,
int width, int height, Color bgcolor, ImageObserver observer);
L’interface Observer comport une méthode imageUpdate()
appelée chaque fois qu’une nouvelle portion de
l’image est disponible
L'exemple suivant affiche trois images des fichiers C0.jpg,
C1.jpg
et
C2.jpg.
Les fichiers se trouvent dans le répertoire courant
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ImageFrame extends
JFrame{
JPanel pan;
ImageFrame(){
setTitle ("Images") ;
setSize (250, 150) ;
pan = new MyPanel();
add(pan);
addWindowListener(new WndCls());
setVisible(true);
}
class MyPanel
extends JPanel {
public void paintComponent(Graphics g){
int x=10,y=10;
super.paintComponent(g) ;
Image img[]= new Image[3];
for(int i=0;i<img.length;i++){
img[i]=Toolkit.getDefaultToolkit().getImage("C"+i+".jpg");
g.drawImage(img[i], x, y,
70,100,null);
x+=80;
}
repaint();
}
}
public class
WndCls extends WindowAdapter {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
public static void
main(String arg[]){
ImageFrame ifm = new ImageFrame();
}
}
Fig. 10.34 Affichage d'Images