Professional Documents
Culture Documents
Licence 3 MIAGe
Frdrique Carrre (carrere@labri.fr) / Pascal Ferraro (ferraro@labri.fr)
MVC: le principe
Le Rle du Modle
rassemble les diffrentes fonctionnalits de lapplication, sans se soucier des apparences comporte des mthodes permettant lutilisateur davoir des renseignements sur ltat du programme comporte des mthodes permettant de modier ltat du programme doit "enregistrer" toutes ses vues pour pouvoir les notier lors dun changement dtat. comporte des mthodes de "notication" des vues ("notifyXXX(), "reXXXChanged(),...)
Schma de fonctionnement
Le modle encapsule ltat de lapplication rpond aux requetes concernant ltat expose les fonctionnalits de lapplication notifie les vues de tout changement
changement dtat
La vue
le controleur gre le comportement de lapplication transforme les actions de lutilisateur en mise jour du modle selectionne les vues pour les rponses un par fonctionnalit
gre lapparence requiert des misesjour selection de la vue du modle envoie les modifications de actions de lutilisateur lutilisateur au controleur permet au controleur de selectionner la vue
MVC en JAVA
Pour crer vos propres modles en JAVA, vous pouvez utiliser java.util.Observable et java.util.Observer le Modle pourra hriter de la classe Observable: void addObserver(Observer o) // pour ajouter une vue protected void setChanged() // marque le modle comme ayant subi un changement void notifyObservers() // pour indiquer un changement aux vues les vues devront alors implmenter linterface Observer: void update(Observable o, Object arg) // code de mise--jour de la vue quand lobjet observ a chang
Exemple
import java.util.*; public class TemperatureModel extends Observable{ public double getF(){ return temperatureF; } public double getC(){ return (temperatureF - 32.0) * 5.0 / 9.0; } public void setF(double tempF){ temperatureF = tempF; setChanged(); notifyObservers(); \\ call the update() of all observers } public void setC(double tempC){ temperatureF = tempC*9.0/5.0 + 32.0; setChanged(); notifyObservers(); \\ call the update() of all observers } private double temperatureF = 32.0; }
Exemple (suite)
public class SliderGUI implements Observer{ public SliderGUI(TemperatureModel m, int h, int v){ m.addObserver(this); //Observe the temperature model model = m; sliderFrame.getContentPane().add(tempControl); tempControl.addAdjustmentListener(new SlideListener()); ... } \\ Called from the model to update the view public void update(Observable t, Object o){ double temp = ((TemperatureModel) t).getC(); \\ Get the new state tempControl.setValue((int) temp); // Move the slider thumb } class SlideListener implements AdjustmentListener{ public void adjustmentValueChanged(AdjustmentEvent e){ model.setC(tempControl.getValue()); \\ require the model to change } }
private JScrollBar tempControl = new JScrollBar(JScrollBar.HORIZONTAL, 0, 10, private TemperatureModel model = null; private JFrame sliderFrame = new JFrame("Celsius"); }
JTable(TableModel dm, TableColumnModel cm, ListSelectio Les trois modles sont fournis.
JTable(Vector rowData, Vector columnNames) ici, les donnes sont fournies par lignes, sous forme de vecteurs.Programmation vnementielle p.15
Modle de table
Les donnes sont accessible par un modle. Elles peuvent tre stockes ou calcules, de faon transparente. La classe AbstractTableModel implmente les mthodes dun modle de table, sauf - public int getRowCount() - public int getColumnCount() - public object getValueAt(int ligne, int colonne) qui retournent respectivement - le nombre de lignes - le nombre de colonnes - lobjet afcher dans les ligne et colonne indiques (sa mthode toString est utilise).
Un Premier Exemple
En plus des trois mthodes obliges, la fonction getColumClass a t rednie, ce qui produit la justication droite
class SimpleTable extends JPanel { SimpleTable() { setLayout(new BorderLayout()); TableModel dataModel = new AbstractTableModel() { public int getColumnCount() { return 10; } public int getRowCount() { return 10;} public Object getValueAt(int row, int col) { return new Integer((1+row)*(1+col)); } public Class getColumnClass(int column) { return Number.class; } }; JTable table = new JTable(dataModel); add(new JScrollPane(table)); } }
Un deuxime Exemple
Cration du modle de table TableModel model = new ModelInvestment(30, 5, 10); JTable table = new JTable(model); Notre modle de table hrite du modle abstrait: class ModelInvestment extends AbstractTableModel {...} Mthodes implmenter (getColumnName par dfaut, numrote A, B, ...): public int getRowCount() public int getColumnCount() public Object getValueAt(int ligne, int colonne) public String getColumnName(int colonne)
Le modle
class ModelInvestment extends AbstractTableModel { private int annees; private int tauxMin; private int tauxMax; private static double depot = 100000.0; ModelInvestment(int annees, int tauxMin, int tauxMax) { this.annees = annees; this.tauxMin = tauxMin; this.tauxMax = tauxMax; } public int getRowCount() { return annees;} public int getColumnCount() { return tauxMax - tauxMin + 1;} public Object getValueAt(int ligne, int colonne) { double taux = (colonne + tauxMin) / 100.0; double depotFinal = depot * Math.pow(1 + taux, ligne); return NumberFormat.getCurrencyInstance().format(depotFinal); } public String getColumnName(int colonne) { double taux = (colonne + tauxMin) / 100.0; return NumberFormat.getPercentInstance().format(taux); } }
Un troisime exemple
class MyTableModel extends AbstractTableModel { private String[] columnNames = {"First Name","Last Name","Sport", "# of Years","Vegetarian"}; private Object[][] data = { {"Mary", "Campione", "Snowboarding", new Integer(5), new Boolean(false)}, {"Alison", "Huml", "Rowing", new Integer(3), new Boolean(true)}, {"Kathy", "Walrath", "Knitting", new Integer(2), new Boolean(false)}, {"Sharon", "Zakhour", "Speed reading", new Integer(20), new Boolean(true)}, {"Philip", "Milne", "Pool", new Integer(10), new Boolean(false)} }; public int getColumnCount() { return columnNames.length; } public int getRowCount() { return data.length; } public String getColumnName(int col) { return columnNames[col]; } ...
/* if some cells are editable. */ public boolean isCellEditable(int row, int col) { if (col > 2) { return true ; } } /* if some data can change. */ public void setValueAt(Object value, int row, int col) { data[row][col] = value; fireTableCellUpdated(row, col); } }
Les vnements
La classe JTable coute les vnements reus du modle
Le modle a plusieurs mthodes pour signaler des modications de donnes : public void fireTableChanged(TableModelEvent e) public void fireTableDataChanged() public void fireTableStructureChanged() public void fireTableRowsInserted(int firstRow, int las public void fireTableRowsUpdated(int firstRow, int last public void fireTableRowsDeleted(int firstRow, int last public void fireTableCellUpdated(int row, int col) Les colonnes sont rgies par un TableColumnModel qui a ses propres noticateurs dvnements sur les colonnes
Mthodes utiles
La mthode boolean TableModel.isCellEditable(int l, int c) doit renvoyer true si la cellule peut tre modie (par dfaut non)
La mthode public void setRowSelectionAllowed(boolean rowSelection indique si les lignes peuvent tre selectionnes dans ce modle
La mthode public void setSelectionBackground(Color selectionBackg attribue une couleur aux cellules selectionnes