Interface graphique en Java les contrôleurs

Cours interface graphique en Java les contrôleurs, tutoriel & guide de travaux pratiques JAVA en pdf.

Les vues

● une vue est un mode de représentation des données
● souvent un objet graphique, mais ça pourrait être autre chose:
– contenu d’un fichier mappé
– image
– pages web
– etc
● une vue a pour but de montrer les données que son modèle lui fournit
● pour cela, elle met un listener sur son modèle pour savoir quand elle doit se mettre à jour
● fait implicitement pour les objets usuels de Swing, quand on passe un modèle au constructeur d’une vue: final DefaultListModel model=new DefaultListModel(); JList list=new JList(model);
● exemple: liste de nombres avec insertion
final DefaultListModel model=new DefaultListModel(); JList list=new JList(model);
JButton b=new JButton(« Insert random 0-100 number at random position »); b.addActionListener(new ActionListener() {
Random random=new Random();
@Override
public void actionPerformed(ActionEvent e) { int index=random.nextInt(model.getSize()+1); int value=random.nextInt(101); model.add(index,value);
}
});
on est dans la thread Swing, pas de problème
● on peut ajouter d’autres vues sur les mêmes données:
final JMenu menu=new JMenu(« 0 item »); model.addListDataListener(new ListDataListener() {
@Override
public void contentsChanged(ListDataEvent e) { /* Nothing to do because we only add data */
}
@Override
public void intervalAdded(ListDataEvent e) {
int n=model.getSize();
menu.setText(n+ » item »+(n>1? »s »: » »));
for (int i=e.getIndex0();i<=e.getIndex1();i++) {
menu.add(new JMenuItem(model.getElementAt(i).toString()),i);
}
}
@Override
public void intervalRemoved(ListDataEvent e) {
/* Nothing to do because we only add data */
}
});

Les contrôleurs

● contrôleur= »chose » qui demande au modèle de modifier les données
● dans l’exemple précédent, c’était le bouton
● on peut avoir plusieurs contrôleurs
● ils doivent toujours poster leurs demandes au modèle dans la thread Swing!
● exemple: Timer qui incrémente chaque seconde de 1000 un élément tiré au hasard
● nécessite une modification de la vue menu pour tenir compte des changements:
@Override
public void contentsChanged(ListDataEvent e) {
for (int i=e.getIndex0();i<=e.getIndex1();i++) { JMenuItem item=(JMenuItem) menu.getItem(i); item.setText(model.getElementAt(i).toString());
}
}
le Timer n’ajoute ni ne retire d’élément: il en modifie un
existant; c’est donc contentChanged qui est concernée

En résumé

● le MVC, c’est facile: les vues se rafraîchissent en V1 V2 redemandant les valeurs nécessaires au modèle le modèle prévient les vues des M changements avec les méthodes fire…
les contrôleurs demandent des C1 C2 C3 modifications des données au modèle

Un exemple complet

● projet: un Victim Manager pour le syndicat des tueurs en série
● besoins client:
– tenir à jour une liste de victimes, définies par un nom et un état (safe, scared, dead)
– on doit pouvoir modifier l’état d’une victime (safe → scared ou scared → dead)

Les données

● les données seront représentées par le type Victim:
private final String name;
private State state;
public Victim(String name,State state) {
this.name=name;
this.state=state;
}
public State getState() { return state; }
public String getName() { return name; }
/* VALUES saves defensive array copies */
private static final State[] VALUES = State.values();
/* Only classes of the current package will be able to invoke this method */ void upgrade() {
if (state == State.DEAD) throw new IllegalStateException(« Cannot upgrade a dead victim ! »); state = VALUES[state.ordinal() + 1];
}
@Override public String toString() {
return name +  » ( » + state + « ):  » + getComment();
}
public String getComment() {
return state.getComment(name.hashCode());
}
● l’état est défini avec une jolie enum, afin de gérer de beaux commentaires:
public enum State {
SAFE(« smile.png », « Life is beautiful », « The world is great », « Everybody is cool », « I feel groovy baby! »),
SCARED(« scared.png », « Oh my god! Oh my god! Oh my god! », « You’ll never get me! », « I’m scared! », « Please save me! »),
DEAD(« rip.png », « Rest in peace », « dead », « horribly murdered »);
private final ImageIcon icon;
private final String[] comment;
private State(String iconName, String… comment) {
this.icon = new ImageIcon(State.class.getResource(iconName));
this.comment = comment;
}
public ImageIcon getIcon() {
return icon;
}
public String getComment(int n) {
return comment[Math.abs(n) % comment.length];
}
}

Le modèle

● il nous faut un modèle de liste permettant l’ajout et la modification de victimes:
– VictimListModel qui va hériter de AbstractListModel (pas de DefaultListModel, car on aurait plein de méthodes dont on ne veut pas !)
● on va gérer les données avec une
ArrayList<Victim>:
ArrayList<Victim> victims=new ArrayList<Victim>();
● on ajoute et obtient les victimes normalement:
@Override
public Victim getElementAt(int index) {
return victims.get(index);
}
@Override
public int getSize() {
return victims.size();
}
public void addVictim(Victim v) {
int size=getSize();
victims.add(v);
fireIntervalAdded(this,size,size);
}
le modèle prévient de l’ajout.

……….

Cours gratuitTélécharger le cours complet

Télécharger aussi :

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *