Outils pour utilisateurs

Outils du site


helloworld:design_pattern:mvc:java:swing_simple
Main.java
package com.llgc;
 
import com.llgc.ctrl.CtrlNombre;
import com.llgc.modele.MdlNombre;
import com.llgc.vue.Fenetre;
 
public class Main {
 
  public static void main(String[] args) {
    // Instanciation de notre modèle
    // Le modèle n'est lié à aucune information.
    MdlNombre nombre = new MdlNombre(0);
    // Création du contrôleur
    // Le contrôleur doit savoir quel objet il contrôle.
    CtrlNombre ctrl = new CtrlNombre(nombre);
    // Création de notre fenêtre avec le contrôleur en paramètre
    // La fenêtre est obligatoirement liée au contrôleur.
    Fenetre fenetre = new Fenetre(ctrl);
 
    // Ajout de la fenêtre comme observeur de notre modèle
    nombre.addObserver(fenetre);
  }
}
MdlNombre.java
package com.llgc.modele;
 
import java.util.EnumSet;
import java.util.Observable;
 
// Le modèle est observable par les vues.
public class MdlNombre extends Observable {
  private int nombre;
 
  public synchronized int getNombre() {
    return nombre;
  }
 
  public synchronized void setNombre(int nombre) {
    this.nombre = nombre;
    setChanged(ChangeNombre.NOMBRE);
    notifyObservers(changeEnum);
    changeEnum = EnumSet.noneOf(ChangeNombre.class);
  }
 
  public MdlNombre(int nombre) {
    super();
    this.nombre = nombre;
    // Initialisation de l'énumération des modifications à vide.
    changeEnum = EnumSet.noneOf(ChangeNombre.class);
  }
 
  // Pour se souvenir quelles propriétés ont été modifiées (si besoin).
  public enum ChangeNombre {
    NOMBRE;
  }
 
  private EnumSet<ChangeNombre> changeEnum;
 
  // setChanged est mis en synchronized car il l'est dans Observable.
  protected synchronized void setChanged(ChangeNombre changeEnum_) {
    setChanged();
    changeEnum.add(changeEnum_);
  }
}
CtrlNombre.java
package com.llgc.ctrl;
 
import com.llgc.modele.MdlNombre;
 
public class CtrlNombre {
  private MdlNombre nombre;
 
  // Le contrôleur surveille le modèle Nombre.
  public CtrlNombre(MdlNombre nombre) {
    super();
    this.nombre = nombre;
  }
 
  // Méthode validant les demandes de modifications de l'IHM.
  public Boolean setNombre(String nbStr) {
    try {
      nombre.setNombre(Integer.parseInt(nbStr));
      return true;
    } catch (NumberFormatException e) {
      return false;
    }
  }
}
Fenetre.java
package com.llgc.vue;
 
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.util.EnumSet;
import java.util.Observable;
import java.util.Observer;
 
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
 
import com.llgc.ctrl.CtrlNombre;
import com.llgc.modele.MdlNombre;
import com.llgc.modele.MdlNombre.ChangeNombre;
 
public class Fenetre extends JFrame implements Observer {
  private static final long serialVersionUID = 2474983998400143732L;
 
  private CtrlNombre ctrl;
  private JTextField bt;
 
  // La fenêtre communique au contrôleur les modifications.
  public Fenetre(CtrlNombre ctrl) {
    super();
    this.ctrl = ctrl;
 
    // IHM ultra simple.
    getContentPane().setLayout(new BorderLayout());
 
    JPanel pnl2 = new JPanel();
    pnl2.add(new JButton(new ActionChangeNombre("Modifier")));
 
    bt = new JTextField(25);
    pnl2.add(bt);
 
    getContentPane().add(pnl2);
 
    pack();
    setVisible(true);
  }
 
  // Informations reçues de la part du modèle
  @Override
  public void update(Observable o, Object arg) {
    if (o instanceof MdlNombre) {
      MdlNombre nb = (MdlNombre)o;
 
      // Il n'est pas possible de caster un Object vers un EnumSet<ChangeNombre> sans warning.
      @SuppressWarnings("unchecked")
      EnumSet<ChangeNombre> cg = (EnumSet<ChangeNombre>)arg;
 
      // Traitement des modifications.
      // Ici, on se contente d'afficher les modif dans la console.
      System.out.println(nb.getNombre());
      for (ChangeNombre iterable_element : cg) {
        System.out.println(iterable_element.toString());
      }
    }
  }
 
  // Événement associé au bouton changeant la valeur du nombre.
  private class ActionChangeNombre extends AbstractAction {
    private static final long serialVersionUID = 4927921822320583419L;
 
    public ActionChangeNombre(String name) {
      super(name);
    }
 
    @Override
    public void actionPerformed(ActionEvent arg0) {
      // Le contrôleur communique avec l'IHM uniquement via le code retour.
      // Si true, le contrôleur a transmis la demande au modèle qui l'a traité avec succès.
      // false si le contrôleur n'a pas transmis la demande au modèle ou
      //       si le modèle a rejeté la demande de modification.
      // Il est préférable en cas de refus que la notification vienne du contrôleur
      // sinon, c'est tous les utilisateurs qui seront notifiés de l'échec et pas uniquement
      // le demandeur.
      if (!ctrl.setNombre(bt.getText())) {
        System.out.println(bt.getText() + " est incorrect.");
      }
    }
  }
}
helloworld/design_pattern/mvc/java/swing_simple.txt · Dernière modification : 2016/11/28 00:13 de root