Exercices

Fermer une fenêtre

Reprendre l’exercice de mise en place d’un formulaire question-réponse.

Maintenant nous allons tente de mettre en place un arrêt "propre" de l’application.

Pour pouvoir activer la fermeture de la fenêtre il faut gérer sur l’objet la méthode windowclosing(WindowEvent we) du contrat de WindowListener.

On réaliser l’exercice en deux temps:

  • D’abord en utilisant l’appel System.exit(0) -qui est plutot violent puiqu’il arrête carrément la machine virtuelle-

  • Ensuite en utilisant la méthode dispose de Window.

Cet exercice a pour objectif de vous faire prendre conscience de problèmes architecturaux qui seront abordés dans la suite du cours.

Gestion événements: cas simple

Reprendre l’exercice de mise en place d’un formulaire question-réponse.

Mettre en place un veilleur des type ActionListener à la fois sur le bouton, et le champs de saisie.

Sur validation on affiche en écho un petit message contenant le chaîne saisie. (utiliser les méthodes getText de TextField et setText de TextArea).

Gestion événements: cas plus général

Jusqu'à présent le code qui réagissait aux événements était étroitement lié au code graphique. Il est souvent de bonne pratique de séparer le code graphique et le code "métier": par exemple notre IHM question-réponse pourrait être utilisée dans des circonstances très différentes (pour répondre à un besoin très général: on pose une question et un mécanisme fournit la réponse qui est alors affichée).

Essayez de réorganiser votre code pour que le mécanisme auquel on fournit une chaîne et qui nous rend une chaîne soit "extérieur" au code graphique.

Faites une première implantation avec cette fonction d'écho : nous réutiliserons ultérieuremnt l’interface graphique pour d’autres exercices!

un "main" de lancement -code controleur- s’appuyant sur cette classe "modèle" simple: ICI

Exemples

Fermer une fenêtre

package org.labs.ihm;

import java.awt.Frame;
import java.awt.Window;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class FermeEcran1 {

   public static void main(String[] args) {
      final Frame fen = new Frame("disposition");
      fen.add(new Ecran1());
      fen.pack();
      fen.addWindowListener(new Fermoir(fen));
      fen.setVisible(true);
   }
}

// une deuxième classe (non publique) dans le fichier.
// plusieurs solutions sont possibles!!!!
class Fermoir extends WindowAdapter {
   Window fenêtre;

   Fermoir(Window fenêtre) {
      this.fenêtre = fenêtre;
   }

   public void windowClosing(WindowEvent evt) {
      fenêtre.dispose();
   }
}

Gestion événements: cas simple

package org.labs.ihm;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Frame;
import java.awt.Label;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class EcranEcho extends Panel {
 private TextArea affichage = new TextArea(10,60);
    private Label invite ;
    private TextField saisie = new TextField(40);
    private Button bouton = new Button("OK");

    private class Echo implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            // partie graphique
           String question = saisie.getText() ;
           // partie fonctionelle
           String réponse = "on a saisi : " + question ;
           // partie graphique
           affichage.setText(réponse);

        }

    }

    public EcranEcho(String invt) {
        this.setLayout(new BorderLayout(3,3 ));
        invite = new Label(invt) ;
        Panel pInvite = new Panel(new BorderLayout());
        {// gestion du Panel des invites
            pInvite.add(invite, BorderLayout.WEST);
            pInvite.add(saisie, BorderLayout.CENTER);
       Panel panBouton = new Panel();
       {
          panBouton.add(bouton) ;
       }
            pInvite.add(panBouton, BorderLayout.SOUTH);

        }
        this.add(pInvite, BorderLayout.NORTH);
        this.add(affichage, BorderLayout.CENTER);
        // gestion événements
        Echo echo = new Echo() ;
        saisie.addActionListener(echo);
        bouton.addActionListener(echo) ;
    }

       public static void main(String[] args) {
                final Frame fen = new Frame("avec echo");
                fen.add(new EcranEcho("tapez ci après ... "));
                fen.pack() ;
                fen.addWindowListener(new WindowAdapter(){
                    public void windowClosing(WindowEvent evt){
                        fen.dispose() ;
                    }
                });
                fen.setVisible(true);
    }
}

Gestion événements: cas plus général

package org.labs.ihm;


public interface Repondeur {
    public String repondA(String question )throws Exception ;
}
package org.labs.ihm;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Label;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class QuestionReponse extends Panel {

    private TextArea affichage = new TextArea(10, 60);
    private Label invite;
    private TextField saisie = new TextField(40);
    private Button bouton = new Button("OK");
    private Repondeur repondeur;

    private class Reaction implements ActionListener {

        public void actionPerformed(ActionEvent arg0) {
            // partie graphique
            String question = saisie.getText();
            // partie fonctionelle
            String réponse = "";
            try {
                réponse = repondeur.repondA(question);
            } catch (Exception exc) {
                réponse = "ERREUR " + exc;
            }
            // partie graphique
            affichage.setText(réponse);

        }
    }


    public QuestionReponse(String invt, final Repondeur repondeur) {
        this.setLayout(new BorderLayout(3, 3));
        this.repondeur = repondeur;
        invite = new Label(invt);
        Panel pInvite = new Panel(new BorderLayout());
        {// gestion du Panel des invites (internationalisé)
            pInvite.add(invite, BorderLayout.LINE_START);
            pInvite.add(saisie, BorderLayout.CENTER);
       // classe anonyme aveec bloc init instance! (très particulier)
       /* new Panel() {
             {this.add(bouton);}// bloc initialisation
      }
        */
            pInvite.add( new Panel() {{add(bouton);}}, // NE PAS ABUSER de ce dispositif
          BorderLayout.PAGE_END);

        }
        this.add(pInvite, BorderLayout.PAGE_START);
        this.add(affichage, BorderLayout.CENTER);
        // gestion événements
        ActionListener veilleur = new Reaction();
        saisie.addActionListener(veilleur);
        bouton.addActionListener(veilleur);
    }
}
package org.labs.ihm;

import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;


public class LanceurEcho {
 public static void main(String[] args) throws Exception {

           final Frame fen = new Frame("Répondeur avec echo");
           fen.add(new QuestionReponse("tapez ci après ... ", new Echo()));
           fen.pack() ;
           fen.addWindowListener(new WindowAdapter(){
               public void windowClosing(WindowEvent evt){
                   fen.dispose() ;
               }
           });
           fen.setVisible(true);
    }
}
package org.labs.ihm;

public class Echo implements Repondeur{

    @Override
    public String repondA(String question) throws Exception {
        return question ;
    }

}
package org.labs.ihm;

import java.awt.Frame;

/**/
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

/**
 * on pourrait paramétrer au lancement l'intitulé de la question posée
 * puis passer le nom de la classe Répondeur.
 * Essayer avec Echo.
 *
 */
public class LanceurDyn {
    public static void main(String[] args) throws Exception {
           Repondeur repondeur = (Repondeur) Class.forName(args[0]).newInstance() ;
           final Frame fen = new Frame("Répondeur : ");
           fen.add(new QuestionReponse("question ... ", repondeur));
           fen.pack() ;
           fen.addWindowListener(new WindowAdapter(){
               public void windowClosing(WindowEvent evt){
                   fen.dispose() ;
               }
           });
           fen.setVisible(true);
    }
}