0% ont trouvé ce document utile (0 vote)
13 vues59 pages

Introduction aux composants Swing en Java

Le document présente les classes SWING en Java, qui permettent de créer des interfaces utilisateur, en se concentrant sur la gestion des événements des composants tels que JButton, JComboBox et JCheckBox. Il décrit également les gestionnaires de placement pour organiser les composants dans les conteneurs, notamment FlowLayout, GridLayout et BorderLayout. Enfin, il aborde la création de fenêtres, de menus, de boîtes de dialogue et de sélection de fichiers.

Transféré par

aMOR BENGOURICH
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 PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
13 vues59 pages

Introduction aux composants Swing en Java

Le document présente les classes SWING en Java, qui permettent de créer des interfaces utilisateur, en se concentrant sur la gestion des événements des composants tels que JButton, JComboBox et JCheckBox. Il décrit également les gestionnaires de placement pour organiser les composants dans les conteneurs, notamment FlowLayout, GridLayout et BorderLayout. Enfin, il aborde la création de fenêtres, de menus, de boîtes de dialogue et de sélection de fichiers.

Transféré par

aMOR BENGOURICH
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 PDF, TXT ou lisez en ligne sur Scribd

Les SWING

Intérêt

• Les Swing est un ensemble de classes permettant de construire des interfaces


utilisateur en Java :
• JFrame,
• JDialog,
• JButton
• JPanel,
• ...

• Les actions de l’utilisateur sur les composants SWING sont gérés par des
événements (clic sur la souris, appui sur une touche, ...)

Benoît Charroux - SWING - janvier 2006 - 2


Le principe des événements
• Gérer les événements de la souris
Component JButton
sur un composant.

1/ Un composant doit s’enregistrer addMouseMotionListener


comme récepteur d’événements.
MouseListener MaClasse
2/ Un objet doit traiter les
événements reçus.
mouseEntered
mouseExited
class MaClasse implements MouseListener{
mousePressed
// ...
{ mouseReleased
JButton boutonCommande = new JButton( "Texte du bouton" ) ;
[Link]( this ) ; // s’enregistre en récepteur
}
public void mouseClicked( MouseEvent e ){ // … } // recevoir les événements
public void mouseEntered(MouseEvent e){} ;
public void mouseExited(MouseEvent e){} ;
public void mousePressed(MouseEvent e){} ;
public void mouseReleased(MouseEvent e){} ;
} Benoît Charroux - AWT - Avril 99 - 3
Le principe des événements
• Gérer les événements de la souris pour faire des dessins sur un objet de type JPanel.
Component JPanel

addMouseMotionListener

MouseMotionListener MaClasse

mouseDragged
mouseMoved

class MaClasse extends JPanel implements MouseMotionListener{


// ...
{
addMouseMotionListener( this ) ; // s’enregistre en récepteur
}
public void mouseDragged( MouseEvent e ){ // … } ; // recevoir les événements
public void mouseMouved(MouseEvent e){ // … } ;
}
Benoît Charroux - SWING - janvier 2006 - 4
Le principe des événements
• Gérer les événements des composants : JButton, JList, JMenu, JTextField.

Component JButton
1/ Un Button peut s’enregistrer
comme récepteur d’événements. addActionListener
2/ Un objet avec un bouton
ActionListener MaClasse
doit traiter les événements reçus.

actionPerformed
class MaClasse implements ActionListener{
// ...
{
JButton bouton = new JButton( "Texte du bouton" ) ;
[Link]( this ) ; // s’enregistre en récepteur
}
public void actionPerformed( ActionEvent e ){ // recevoir les événements
// …
}
}
Benoît Charroux - SWING - janvier 2006 - 5
Les événements
• Gérer les événements des composants : JComboBox, JCheckBox.

JComboBox
1/ Un Choix peut s’enregistrer
comme récepteur d’événements. addItemListener
2/ Un objet avec un choix doit
ItemListener MaClasse
traiter les événements reçus.

itemStateChanged
class MaClasse implements ItemListener{
// ...
{
JComboBox box = new JComboBox() ; // crée un sélecteur
[Link]( this ) ; // s’enregistre en récepteur
}
public void itemStateChanged( ItemEvent e ){ // gère les événements
// ...
}
}
Benoît Charroux - SWING - janvier 2006 - 6
public class Main{
Les frames
public static void main( String[] argv ){
Fenêtre frame = new Fenêtre() ;
}
}
public class Fenêtre extends JFrame impements WindowListener{
public Fenêtre(){
setTitle( "titre de la fenêtre" ) ;
setSize( 200, 200 ) ;
addWindowListener( this );
setVisible( true ) ;
}
public void windowActived( WindowEvent e ){}
public void windowClosed( WindowEvent e ){}
public void windowClosing( WindowEvent e ){ dispose(); [Link](0); }
public void windowDeactived( WindowEvent e ){}
public void windowDeiconified( WindowEvent e ){}
public void windowIconified( WindowEvent e ){}
public void windowOpened( WindowEvent e ){}
}
Benoît Charroux - SWING - janvier 2006 - 7
Les menus
public class Fenêtre extends JFrame {
public Fenêtre(){
// ...
JMenu menu = new JMenu( "Fichier" ) ;

JMenuItem item = new JMenuItem( "item" ) ;


[Link]( item ) ;

JMenuItem quitter = new JMenuItem( "Quitter" ) ;


[Link]( quitter ) ;

JMenuBar menuBarre = new JMenuBar() ; // créé une barre de menu


[Link]( menu ) ; // ajoute un menu à la barre
setJMenuBar( menuBarre ) ; // ajoute la barre à la Frame
}
}

Benoît Charroux - SWING - janvier 2006 - 8


Gérer les événements des menus

public class Fenêtre extends Frame implements ActionListener {


public Fenêtre(){
// ...
JMenuItem item = new JMenuItem( "item" ) ;
[Link]( this ) ; // enregistrer en récepteurs d’événements
[Link]( item ) ;
JMenuItem quitter = new JMenuItem( "Quitter" ) ;
[Link]( this ) ; // enregistrer en récepteurs d’événements
[Link]( quitter ) ;
}

public void actionPerformed( ActionEvent e ){


if( [Link]().equals( "Quitter" ) ) // item quitter :
dispose() ; // libérer ressource
if( [Link]().equals( "item" ) )
[Link]( "item choisit" ) ;
}
}

Benoît Charroux - SWING - janvier 2006 - 9


Les sélecteurs de choix

class Fenêtre extends JFrame implements ItemListener {


Fenêtre(){
// ...
getContentPane().add( new Label( "choisir :" ) ) ;

JComboBox choix = new JComboBox() ;


[Link]( "choix 1" ) ;
[Link]( "choix 2" ) ;
[Link]( this ) ;
getContentPane().add( choix ) ;
}

public void itemStateChanged( ItemEvent e ){ // gère les événements


if( [Link]().equals( "choix 1" ) ) // si premier item
[Link]( "premier choix" ) ;
if( [Link]().equals( "choix 2" ) ) // si deuxieme item
[Link]( "deuxieme choix" ) ;
}
}
Benoît Charroux - SWING - janvier 2006 - 10
Les cases à cocher 1/4

JLabel

JCheckbox à choix unique :


CheckboxGroup

JCheckbox à choix multiple :


JCheckbox regroupée dans un Panel

JBouton dans un JPanel pour qu’il


n’occupe pas la largeur de la fenêtre

Benoît Charroux - SWING - janvier 2006 - 11


Les cases à cocher 2/4
public class ChoixMenu extends JApplet{
private JPanel saucePanel = new JPanel() ;
private CheckboxGroup platGroup = new CheckboxGroup() ;

public void init(){


JCheckbox c ;
JPanel platPanel = new JPanel() ;
[Link]( c = new JCheckbox( "Beurk Burger" ) ) ;
[Link]( platGroup ) ;
[Link]( c = new JCheckbox( "Plastic chicken" ) ) ;
[Link]( platGroup ) ;
[Link]( true ) ;

[Link]( new JCheckbox( "Sauce degeu" ) ) ;


[Link]( new JCheckbox( "Sauce affreuse" ) ) ;
}
}

Benoît Charroux - SWING - janvier 2006 - 12


Les cases à cocher : mise en forme 3/4
public class ChoixMenu extends JApplet{
private JPanel saucePanel = new JPanel() ;
private CheckboxGroup platGroup = new CheckboxGroup () ;

public void init(){

// ...
JPanel platPanel = new JPanel() ;
JPanel commandePanel = new JPanel() ;

setLayout( new GridLayout( 5, 1 ) ) ;


add( new JLabel( "Choisir parmi :" ) ) ;
add( platPanel ) ;
add( new JLabel( "Choisir une ou plusieurs sauces :" ) ) ;
add( saucePanel ) ;
add( commandePanel ) ; // voir page suivante
resize( getPreferredSize() ) ;
}
}

Benoît Charroux - SWING - janvier 2006 - 13


Les cases à cocher : gérer les événements 4/4
public class ChoixMenu extends JApplet implements ActionListener {

public void init(){


JPanel commandePanel = new JPanel() ;
JButton boutonCommande = new JButton( "Passer commande" ) ;
[Link]( this ) ;
// ...
}
public void actionPerformed( ActionEvent e ){
if( [Link]().equals( "Passer commande" ) ){
JCheckbox c = [Link]() ;
[Link]( [Link]() ) ;
Component [] composants = [Link]() ;
for( int i=0; i<[Link]; i++ )
if( (c = (JCheckbox)composants[i]).getState() )
[Link]( "Avec " + [Link]() ) ;
[Link]( "Merci !" ) ;
}
}
}
Benoît Charroux - SWING - janvier 2006 - 14
Les boîtes de dialogues 1/2
class MaBoite extends JDialog implements ActionListener{

MaBoite(){
setModal( true ) ;
setLayout( new BorderLayout() );
getContentPane().add( new JLabel( "Bart dit" ),
[Link] ) ;
JPanel panel = new JPanel() ;
JButton boutonCompris = new JButton( "Cool mec !" ) ;
[Link]( this ) ;
[Link]( boutonCompris ) ;
JButton boutonPasCompris = new JButton( "D’ho !" ) ;
[Link]( this ) ;
[Link]( boutonPasCompris ) ;
getContentPane(). add( panel, [Link] ) ;
pack() ;
setVisible( true );
}
// …
} Benoît Charroux - SWING - janvier 2006 - 15
Les boîtes de dialogues 2/2

class MaBoite extends JDialog implements ActionListener{

public void actionPerformed( ActionEvent e ){


if( [Link]().equals( "Compris !" ) )
setVisible( false ) ;
dispose();
else
[Link]( "Comprends rien !" ) ;
}

public static void main( String [] argv ){


MaBoite boite = new MaBoite()
}
}

Benoît Charroux - AWT - Avril 99 - 16


Les boîtes de sélection de fichiers : ouvrir un fichier 1/3
public class Editeur extends JFrame {
public Editeur(){
// gestion d’un menu
}
public void loadFile(){
JFileChooser f = new JFileChooser();
[Link]( this );
}
public static void main( String [] argv ){
new Editeur();
}
}

Benoît Charroux - SWING - janvier 2006 - 17


Les boîtes de sélection de fichiers : ouvrir un fichier 2/3
public class Editeur extends JFrame {

public void loadFile(){


JFileChooser chooser = new JFileChooser();
int returnVal = [Link]( this );
if( returnVal == JFileChooser.APPROVE_OPTION ){
String fileName = [Link]().getName();
try{
FileInputStream fis = new FileInputStream( fileName ) ;
byte [] donnees = new byte[ [Link]() ] ;
[Link]( donnees ) ;
[Link]() ;
// ...
} catch( IOException e ) {
// ...
}
}
}
}

Benoît Charroux - SWING - janvier 2006 - 18


Les boîtes de sélection de fichiers : ouvrir un fichier 3/3

public class Editeur extends JFrame {

private JTextArea zoneTexte = new JTextArea() ;

public void loadFile(){


// ...
try{
// ...
[Link]( new String( donnees, 0 ) ) ; // affiche dans zoneTexte
} catch( IOException e ) {
[Link]( "Impossible de charger le fichier : " + [Link]() ) ;
}
}
}

Benoît Charroux - SWING - janvier 2006 - 19


Les boîtes de sélection de fichiers : utiliser un menu
class Editeur extends JFrame implements ActionListener{

public Editeur(){
super( "Editeur" ) ;
add( "Center", zoneTexte ) ; // ajout du texte

JMenu menu = new JMenu( "Fichier" ) ;


JMenuItem charger = new JMenuItem( "Charger" ) ;
[Link]( this ) ; // s’enregistre en récepteur d’événements
[Link]( charger ) ; // ajoute le menuItem au menu
// idem pour Sauvegarder
// idem pour Quitter

JMenuBar menuBar = new JMenuBar() ; // créé une barre de menu


[Link]( menu ) ; // ajoute le menu
setJMenuBar( menuBar ) ; // ajoute la barre à la frame
pack() ; // ajuste la taille des composants
}
}
Benoît Charroux - SWING - janvier 2006 - 20
Les boîtes de sélection de fichiers : intercepter les événements

public class Editeur extends JFrame implements ActionListener{

public void actionPerformed( ActionEvent e ){

if( [Link]().equals( "Charger" ) )


loadFile() ;
}

Benoît Charroux - SWING - janvier 2006 - 21


Le gestionnaire de placement

• Le gestionnaire de placement (*Layout) permet de disposer le composants


(Component) dans un conteneur (Container) :

• flow layout,

• border layout,

• grid layout,

• Card layout,

• Box layout,

• ...

Benoît Charroux - SWING - janvier 2006 - 22


Le gestionnaire de placement FlowLayout

• Les conteneurs Panel et Applet ont le gestionnaire de placement FlowLayout par


défaut : les composants sont placés de gauche à droite et de haut en bas.

public class Flow extends JApplet{


public void init(){
add( new JButton( "un" ) ) ;
add( new JButton( "deux" ) ) ;
add( new JButton( "trois" ) ) ;
add( new JButton( "quatre" ) ) ;
add( new JButton( "cinq" ) ) ;
}
}

Benoît Charroux - SWING - janvier 2006 - 23


Le gestionnaire de placement GridLayout
• Le gestionnaire de placement GridLayout place les composants selon une grille ;
• mettre en place un nouveau gestionnaire se fait avec
setLayout( new GridLayout( 3, 2 ) ) ;

public class Grid extends JApplet{


public void init(){
setLayout( new GridLayout( 3, 2 ) ) ;
add( new JButton( "un" ) ) ;
add( new JButton( "deux" ) ) ;
add( new JButton( "trois" ) ) ;
add( new JButton( "quatre" ) ) ;
add( new JButton( "cinq" ) ) ;
}
}

Benoît Charroux - SWING - janvier 2006 - 24


Le gestionnaire de placement BorderLayout
• Le gestionnaire de placement GridLayout place les composants selon une position
géographique par rapport au bord de la fenêtre.

public class Border extends JApplet{


public void init(){
setLayout( new BorderLayout() ) ;
add( new JButton( "un" ), [Link] ) ;
add( new JButton( "deux" ), [Link] ) ;
add( new JButton( "trois" ), [Link] ) ;
add( new JButton( "quatre" ), [Link] ) ;
add( new JButton( "cinq" ), [Link] ) ;
}
}

Benoît Charroux - SWING - janvier 2006 - 25


Le gestionnaire de placement CardLayout 1/2
• Le gestionnaire de placement CardLayout permet d’enchaîner des écrans.
public class Card extends JApplet implements ActionListener{
private CardLayout cartes = new CardLayout() ;
private JPanel panel1 = new JPanel() ;
private JPanel panel2 = new JPanel() ;

public void init(){


setLayout( cartes ) ;
add( "un", panel1 ) ;
add( "deux", panel2 ) ;
}

public void actionPerformed( ActionEvent e ){


if( [Link]().equals( "Suivant" ) )
[Link]( this ) ; // passe au panel suivant
if( [Link]().equals( "Terminer" ) ){
// ...
}
}
} Benoît Charroux - SWING - janvier 2006 - 26
Le gestionnaire de placement CardLayout 2/2

public class Card extends JApplet implements ActionListener{


private JPanel panel1 = new JPanel() ;

public void init(){


[Link]( new JCheckbox( "Choix 1" ) ) ;
[Link]( new JCheckbox( "Choix 2" ) ) ;
JButton bouton = new JButton( "Suivant" ) ;
[Link]( this ) ;
[Link]( bouton ) ;
}

// ...
}

Benoît Charroux - SWING - janvier 2006 - 27


Les
view
et les
Model
Le view et les model illustrés par une JTable

public class MixerInfoPanel extends JPanel{


public MixerInfoPanel(){

super(new GridLayout(1,0));

JTable table = new JTable( new MyTableModel() );


[Link](new Dimension(700, 70));
[Link]( [Link], new MixerRenderer() );
[Link]( [Link], new MixerEditor() );
JScrollPane scrollPane = new JScrollPane( table );

add( scrollPane );
}
}

Benoît Charroux - SWING - janvier 2006 - 29


Le view et les model illustrés par une JTable
class MyTableModel extends AbstractTableModel {
private String[] columnNames = { "", "nom", "description", "vendeur", "version" };

private Object[][] data;

public MyTableModel(){
[Link][] infos = [Link]();
data = new Object[[Link]][5];
for( int i=0; i<[Link]; i++ ){
data[i][0] = infos[i];
data[i][1] = infos[i].getName();
data[i][2] = infos[i].getDescription();
data[i][3] = infos[i].getVendor();
data[i][4] = infos[i].getVersion();
}
}

Benoît Charroux - SWING - janvier 2006 - 30


Le view et les model illustrés par une JTable
class MyTableModel extends AbstractTableModel {
public int getColumnCount() {
return [Link];
}
public int getRowCount() {
return [Link];
}
public String getColumnName(int col) {
return columnNames[col];
}
public Object getValueAt(int row, int col) {
return data[row][col];
}
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
public boolean isCellEditable(int row, int col) {
if (col > 0) return false;
else return true;
}
}

Benoît Charroux - SWING - janvier 2006 - 31


Le view et les model illustrés par une JTable
class MixerEditor extends AbstractCellEditor implements TableCellEditor, ActionListener{
[Link] info;
JButton button;
protected static final String EDIT = "afficher les caractéristiques";
public MixerEditor() {
button = new JButton();
[Link](EDIT);
[Link](this);
}
public void actionPerformed(ActionEvent e) {
if ([Link]([Link]())) {
JDialog dialog = new JDialog();
[Link]( "Mixer" );
MixerPanel mixerPanel = new MixerPanel( ([Link])getCellEditorValue() );
[Link]().add( mixerPanel );
[Link]();
[Link]( true );
fireEditingStopped();
}
}
}
Benoît Charroux - SWING - janvier 2006 - 32
Le view et les model illustrés par une JTable
class MixerRenderer extends JLabel implements TableCellRenderer {

public MixerRenderer() {
setOpaque(true);
}

public Component getTableCellRendererComponent


( JTable table, Object color, boolean isSelected, boolean hasFocus, int row, int column){
setBackground( [Link] );
setToolTipText( "Afficher les caractéristiques du mixer" );
return this;
}
}

Benoît Charroux - SWING - janvier 2006 - 33


Le view et les model illustrés par une JTable

Benoît Charroux - SWING - janvier 2006 - 34


Le view et les model illustrés par une JTable
public class MixerPanel extends JPanel{
public MixerPanel( [Link] mixerInfo ){
setLayout( new BoxLayout(this, BoxLayout.PAGE_AXIS) );
setBorder( [Link](5,5,5,5) );

add( [Link](new Dimension(0, 5)) );


add( new JLabel([Link]()) );

add( [Link](new Dimension(0, 5)) );


SourceDataLinePanel sourceDataLinePanel = new SourceDataLinePanel( mixerInfo );
add( sourceDataLinePanel );

add( [Link](new Dimension(0, 5)) );


TargetDataLinePanel targetDataLinePanel = new TargetDataLinePanel( mixerInfo );
add( targetDataLinePanel );

add( [Link](new Dimension(0, 5)) );


PortPanel portPanel = new PortPanel( mixerInfo );
add( portPanel );

add( [Link]() );
}
}
Benoît Charroux - SWING - janvier 2006 - 35
Le

Graphisme
avec les

SWING
Le dessin des composants
• la méthode paint permet de peindre un composant, elle est appelée la première fois
qu’un composant s’affiche et quand c’est nécessaire ;
• si une application veut redessiner un composant, il peut appeler la méthode repaint ;
• repaint est chargé de planifier le dessin du composant qui sera redessiné par appel de
la méthode update ;
• update efface le composant puis appelle la méthode paint.

Component
Button
paint( Graphics g )
repaint ...
update( Graphics g )

Un objet de type Graphics définit le contexte d’affichage d’un composant, et permet


de réaliser des dessins.

Benoît Charroux - SWING - janvier 2006 - 37


Le dessin des composants

Graphics

setColor Fixe la couleur du dessin dans un composant


fillRect
fillPolygon
Dessin de formes pleines
fillOval
fillArc
draw… Dessin de formes vides
drawString Affiche un message
...

Benoît Charroux - SWING - janvier 2006 - 38


0
Exemple
public class Dessin extends JApplet{
0
public void paint( Graphics graphic ){
int appLargeur = getSize().width ;
int appHauteur = getSize().height ;
int largeur = appLargeur/2 ;
int hauteur = appHauteur/2 ;
int x = (appLargeur - largeur)/2 ;
int y = (appHauteur - hauteur)/2 ;
int [] polyX = { 0, appLargeur/2, appLargeur, appLargeur/2 } ;
int [] polyY = { appHauteur/2, 0, appHauteur/2, appHauteur } ;
Polygon poly = new Polygon( polyX, polyY, 4 ) ;
[Link]( [Link] ) ;
[Link]( 0, 0, getSize().width, getSize().height ) ;
[Link]( [Link] ) ;
[Link]( poly ) ;
[Link]( [Link] ) ; Coordonnées des angles
[Link]( x, y, largeur, hauteur ) ; du polygone
[Link]( [Link] ) ;
[Link]( x, y, largeur, hauteur, 90, 180 ) ;
}
} Benoît Charroux - SWING - janvier 2006 - 39
Les polices de caractères
Graphics

setFont Fixe la police d’un contexte graphique


drawString Affiche un texte
... Font
PLAIN
BOLD Variables
publiques
ITALIC
...

Font font = new Font( "TimesRoman", [Link], 12 ) ; // défini une police


Dialog ;
Helvetica ;
TimesRoman ; Taille en nombre de points de la police.
Courier ;
Symbol.
Benoît Charroux - SWING - janvier 2006 - 40
Le problème du rafraîchissement des images et des dessins
• Cas d’un dessin tournant sur lui même à chaque clic sur la souris (suite du
transparent 4) :
public class Dessin extends JApplet implements MouseListener{
int theta = 90 ;
int largeur, hauteur, x, y ;

public void init(){


addMouseListener( this ) ;
}
public void mouseClicked( MouseEvent e ){
theta = (theta+10) % 360 ;
repaint() ;
}
public void mouseEntered(MouseEvent e){} ;
// ...

public void paint( Graphics graphic ){


// … [Link]( x, y, largeur, hauteur, theta, 180 ) ;
}
} Benoît Charroux - SWING - janvier 2006 - 41
Le problème du rafraîchissement des images et des dessins

• Le passage d’une image à une autre n’est pas fluide, il y a des tremblements !

Benoît Charroux - SWING - janvier 2006 - 42


Première solution
• Ne pas rafraîchir toute l’image mais définir un rectangle autour de la partie
de l’image qui change ;
• Définir le rectangle de rafraîchissement dans la méthode update qui est
appelée par repaint.

public class Dessin extends JApplet implements MouseListener{


// ...
public void mouseClicked( MouseEvent e ){
// ...
repaint() ;
}
public void paint( Graphics graphic ){ // repeint l’image précisée dans le
// … // le contexte graphique g
}
public void update( Graphics g ){
[Link]( x, y, largeur, hauteur ) ; // définition du rectangle à rafraîchir
paint( g ) ; // repeint uniquement le rectangle
}
}
Benoît Charroux - SWING - janvier 2006 - 43
Deuxième solution : le double buffering
• Ce qui prend du temps, ce n’est pas d’afficher mais de dessiner : dessiner dans
une zone tampon (ce qui peut prendre du temps) puis n’afficher que le résultat
(ce qui est toujours rapide).

public class Dessin extends [Link] implements MouseListener{


// ...
public void update( Graphics g ){
// créé une image à la taille de l’applet
Image tampon = createImage( getSize().width, getSize().height ) ;
// récupère son contexte graphique
Graphics graphic = [Link]() ;
// dessine l’image avec le contexte graphique
paint( graphic ) ;
// quand l’image est prête … on l’affiche
[Link]( tampon, 0, 0, this ) ;
// le contexte graphique ne peut être utilisé qu’une seule fois
[Link]() ;
}
}
Benoît Charroux - SWING - janvier 2006 - 44
Application du double buffering au dessin avec la souris 1/4

• Comment reproduire fidèlement les efforts d’un utilisateur faisant n’importe


quoi avec la souris ?

Un objet de
type Canvas

• Dissocier la gestion de la souris de l’affichage.

Benoît Charroux - SWING - janvier 2006 - 45


Dessin avec la souris : définition d’une zone de dessin 2/4
public class Dessiner extends JFrame implements ActionListener{
ZoneDeDessin zoneDeDessin ; // la zone de dessin
public Dessiner {
setLayout( new BorderLayout() ) ; // pour positionner sur les bords
add( zoneDeDessin = new ZoneDeDessin(), [Link] );
JPanel p = new JPanel() ; // zone basse de l’applet avec un bouton
JButton boutonClear = new JButton( "Effacer") ;
[Link]( this ) ; // récepteur d’événements
[Link]( boutonClear ) ; // ajout du bouton ...
add( "South", p ) ; // à la zone basse de l’applet
setVisible( true );
}
public void actionPerformed( ActionEvent e ){ // clic sur le bouton
if( [Link]().equals( " Effacer " ) )
[Link]() ; // efface le dessin
}
}
class ZoneDeDessin extends JPanel {
// ...
}
Benoît Charroux - SWING - janvier 2006 - 46
Dessin avec la souris : gérer l’affichage 3/4

class ZoneDeDessin extends JPanel {


Image drawImg ;
Graphics drawGr ;
public void update( Graphics g ) {
paint(g) ; // update ne fait que peindre
}
public void paint( Graphics g ) { // création d’un buffer, récupère son
if ( drawImg == null ) { // contexte, et prépare un crayon noir
drawImg = createImage( getSize().width, getSize().height ) ;
drawGr = [Link]() ;
[Link]( [Link] ) ;
}
[Link](drawImg, 0, 0, null) ; // affiche le buffer
}
public void clear() { // efface la zone de dessin
[Link]().clearRect(0, 0, getSize().width, getSize().height) ;
repaint() ;
}
}
Benoît Charroux - SWING - janvier 2006 - 47
Dessin avec la souris : gérer la souris 4/4
class ZoneDeDessin extends JPanel implements MouseMotionListener, MouseListener{
int xpos, ypos, oxpos, oypos ; // coordonnées d’un trait

ZoneDeDessin() {
setBackground( [Link] ) ;
addMouseMotionListener( this ) ; // pour l’événement mouseDragged
addMouseListener( this ) ; // pour l’événement mousePressed
}
public void mouseDragged( MouseEvent e ){
xpos=[Link](); ypos=[Link]() ; // mémorise la fin du trait
if ( drawGr != null ) // trace si nécessaire dans le buffer
[Link]( oxpos, oypos, oxpos=xpos, oypos=ypos ) ;
repaint() ; // affiche le dessin avec un nouveau trait
}
public void mousePressed(MouseEvent e){ // mémorise le début du trait
oxpos=[Link]() ; oypos=[Link]() ;
}
}

Benoît Charroux - SWING - janvier 2006 - 48


Les images
Les images sont traités de manière asynchrone : les méthodes qui utilisent des objets
Image retournent immédiatement, mais continuent à s’exécuter en tâche de fond :

public class MonApplet extends [Link]{


// ...
Image img = getImage( "[Link] ) ;
}

La méthode getImage retourne immédiatement, le téléchargement de l’image n’a


lieu que si on en a besoin :

public void paint( Graphics g ){


[Link]( img, 0, 0, this ) ;
}

• Avantages : l’application n’est pas bloquée ;

• Inconvénient : comment savoir quand l’image est disponible pour l’affichage ?


Benoît Charroux - SWING - janvier 2006 - 49
Le MediaTracker

• Les limites des ImageObserver est qu’il faut 1 spectateur par image à charger !
• Comment suivre le chargement de plusieurs images pour une seule application ?

MediaTracker
ABORTED
ERRORED
status des images.
COMPLETE
LOADING Création d’un MadiaTracket pour les images d’un
MediaTracker( Component ) composant
addImage Ajout d’images avec un identificateur.

checkAll - checkID Vérifie si les images sont entièrement chargées


statusAll - statusID Vérifie le status des images.
waitForAll - waitForID Commence et attend la fin du chargement d’images.
...
Benoît Charroux - SWING - janvier 2006 - 50
Exemple d’utilisation du MediaTracker 1/4
Une applet qui charge plusieurs images pour une animation, attend que toutes les
images soient chargées avant d’afficher l’animation.

public class Animation extends JApplet implements Runnable {


MediaTracker tracker ;
Image fond ; // image de fond
Image anim[] = new Image[5] ; // les images animées

public void init(){


tracker = new MediaTracker( this ) ; // créé un MediaTracker pour l’applet
fond = getImage( getCodeBase(), "[Link]" ) ; // l’image de fond
[Link]( fond, 0 ); // id = 0 pour l'image de fond
for (int i = 0; i < 5; i++){ // Les images de l’animation
anim[i] = getImage( getCodeBase(), "anim"+i+".gif" );
[Link]( anim[i], 1 ); // id = 1 pour les animations
}
}
// ...
}
Benoît Charroux - SWING - janvier 2006 - 51
Affiche l’animation quand elle est prête 2/4

public class Animation extends JApplet implements Runnable {


int index ;
// ...
public void update( Graphics g ) {
paint( g ) ; // le fond occupe toute l'applet, pas la peine de l'effacer
}
public void paint( Graphics g ) { // si erreur de chargement
if ( ([Link](false) & [Link]) != 0 ) {
[Link]( [Link] ) ; // affiche un rectangle rouge
[Link]( 0, 0, size().width, size().height ) ;
return ;
}
[Link]( fond, 0, 0, this ) ; // affiche le fond quand il arrive
// si toutes les animations sont pretes ...
if( [Link](1, false) == [Link] )
[Link]( anim[index], 10, 10, this ) ; // affiche les animations
}
}

Benoît Charroux - SWING - janvier 2006 - 52


Créer un thread pour le chargement et l’animation 3/4

public class Animation extends JApplet implements Runnable {


Thread animation ;
// ...
public void start() {
animation = new Thread( this ) ;
[Link]() ; // lance l'animation
}
public void stop() {
[Link]() ; // stoppe l'animation
animation = null ;
}
public void run() {
// ...
}
}

Benoît Charroux - SWING - janvier 2006 - 53


Créer un thread pour le chargement et l’animation 4/4
public class Animation extends JApplet implements Runnable {
// ...
public void run() {
try {
[Link]( 0 ) ; // attend le chargement de l'image de fond
[Link]( 1 ) ; // attend le chargement des images de l’animation
} catch( InterruptedException e ){ return ; }
Thread me = [Link]() ;
while( animation == me ) { // tant que le thread s'exécute
try{
[Link]( 100 ) ; // endort le thread
}catch( InterruptedException e ){ break ; }
synchronized( this ){
index++ ; // passe à l'image suivante
if( index >= [Link] ) index = 0 ;
}
repaint() ; // appel à paint
}
}
}
Benoît Charroux - SWING - janvier 2006 - 54
Le filtrage d’images

Image changée d’échelle

Partie de l’image

Image originale

Image dont on a supprimé la composante rouge

Benoît Charroux - SWING - janvier 2006 - 55


Le filtrage d’images
1 1..*
ImageProducer ImageConsumer ImageObserver
Envoi les renseigne
pixels
FilteredImageSource
ImageFilter

ReplicateScaleFilter CropImageFilter RGBImageFilter


Extraction d’une sous
AreaAveragingScaleFilter image SupprimeRougeFilter

Changement d’échelle Filtre les pixels d’une


image
Image original = getImage( getCodeBase(), "[Link]" ) ;
Image ImageFiltree = createImage(
new FilteredImageSource( [Link](), new SupprimeRougeFilter())
);
producteur producteur consommateur
Benoît Charroux - SWING - janvier 2006 - 56
Filtrer des images
public class Filtage extends JApplet {

Image original, vert, echelle, partie ;

public void init(){


// charge l’image originale
original = getImage( getCodeBase(), "[Link]" ) ;
// créé une image dont on supprimé la composante rouge
vert = createImage( new FilteredImageSource( [Link](),
new SupprimeRougeFilter())) ;
// créé une image avec changement d’échelle
echelle = createImage( new FilteredImageSource( [Link](),
new AreaAveragingScaleFilter( 80, 200 ))) ;
// créé une sous image
partie = createImage( new FilteredImageSource( [Link](),
new CropImageFilter( 10, 10, 50, 50 ))) ;
setLayout( null ) ;
setSize( 430, 270 ) ;
}
}
Benoît Charroux - SWING - janvier 2006 - 57
Afficher les images filtrées
public class Filtage extends JApplet {

Image original, vert, echelle, partie ;

public void init(){


// ...
}
public void paint( Graphics g ) {
int largeur = getSize().width ;
int hauteur = getSize().height ;
[Link]( original, 0, 0, largeur/4, hauteur, this ) ;
[Link]( vert, largeur/4, 0, largeur/4, hauteur, this ) ;
[Link]( echelle, 2*largeur/4, 0, 80, 200, this ) ;
[Link]( partie, 3*largeur/4, 0, 50, 50, this ) ;
}
}

Benoît Charroux - SWING - janvier 2006 - 58


Supprimer la composante rouge d’une image
public class Filtage extends [Link]{
// ...
vert = createImage( new FilteredImageSource( [Link](),
new SupprimeRougeFilter()));
}

class SupprimeRougeFilter extends RGBImageFilter{


public SupprimeRougeFilter(){
canFilterIndexColorModel = true; // le filtrage ne dépend pas
} // de la position des pixels

public int filterRGB( int x, int y, int rgb){


return ((rgb & 0xff00ff00) | ((rgb & 0xff) << 16));
}
} 32 bits

Alpha Rouge Vert Bleu

8 bits
Benoît Charroux - SWING - janvier 2006 - 59

Vous aimerez peut-être aussi