MVC et Swing(en rappel) Introduction à JSF jean-michel...

129
MVC_Swing_JSF 1 MVC et Swing(en rappel) Introduction à JSF Notes de cours jean-michel Douin, douin au cnam point fr version : 31 Octobre 2013

Transcript of MVC et Swing(en rappel) Introduction à JSF jean-michel...

MVC_Swing_JSF1

MVC et Swing(en rappel)Introduction à JSF

Notes de cours

jean-michel Douin, douin au cnampoint frversion : 31 Octobre 2013

MVC_Swing_JSF2

Sommaire

• Evènements, MVC– Usage des patrons

• Observateur, Commande

– Mise en œuvre du Modèle, Vue, Contrôleur– Exemples

• Démonstration

– Le modèle devient un java Bean– MVC d’un composant swing

• L’API Swing– Un descriptif– Exemples

• Démonstration

– Usage des patrons • Composite, stratégie, fabrique …

• JSF présentation– IHM et HTML

• Du swing côté serveur �� de l’HTML côté client

– MVC et Web

MVC_Swing_JSF3

Principale bibliographie utilisée

• Swing, recherche google– http://notes.corewebprogramming.com/student/Basic-Swing.pdf– mathinfo.ens.univ-reims.fr/.../ppt /Swing _et_les_Applications_Graphiques.ppt

• JSF– Mastering JavaServer Faces, ed Wiley

• Bill Dudney,Jonathan Lehr, Bill Willis, LeRoy Mattingly

– JSF-2• http://andyschwartz.wordpress.com/2009/07/31/whats-new-in-jsf-2/• http://javaserverfaces.java.net/presentations/jsf2-complete-tour/jsf2-complete-tour.pdf

– Divers• Certains diagrammes UML : http://www.dofactory.com/Patterns/PatternProxy.aspx• informations générales http://www.edlin.org/cs/patterns.html

MVC_Swing_JSF4

MVC, doc de Sun

• http://java.sun.com/blueprints/patterns/MVC-detaile d.html• Un exemple …

MVC_Swing_JSF5

Interactivité, MVC

• L’interface graphique– La vue

• Interactions avec l’utilisateur– Le contrôle

• Les données de l’application– Le modèle

• A la recherched’une adéquation des données de l’application et de s vues

– Paradigme MVC• Modèle Vue Contrôleur

MVC_Swing_JSF6

MVC un exemple : un nombre !

le modèle: un nombre

Une vueune jauge

• Déploiement ?– IHM ?– Contrôle ?– Modèle ?

50

Un contrôle

37Une vue

37Une JFrame

MVC_Swing_JSF7

Déploiement ? Choix de classes

• Discussion …– Le modèle : la classe Nombre– La Vue : Une JFrame, une jauge, un affichage, des b outons– Le Contrôle : Réactions aux actions de l’utilisateu r …

MVC_Swing_JSF8

Un déploiement possible, démonstration

• La classe Nombre est Observable– Elle hérite de java.util.Observable

• Les Vues sont des observateurs– Elles implémentent java.util.Observer,– Peuvent être des IHM, des « Container » swing,– Sans interface : des vues sans être vues ?…

• Par exemple : un journal des évènements– …

• Les Contrôles gèrent les actions de l’utilisateur– Elles implémentent les XXXXListener des composants s wing– Une classe par action ?

MVC_Swing_JSF9

Exemple un nombre, une vue, un contrôle

public class MainNombreMVC{

public static void main(String[] args){Nombre nombre = new Nombre(0,10); // le modèle

Vue1 vue1 = new Vue1(nombre);

ControleVue1 controle1 = new ControleVue1(nombre, v ue1);

}}

MVC_Swing_JSF10

Le modèlepublic class Nombre extends java.util.Observable{

public final int VALEUR_MIN;public final int VALEUR_MAX;private int valeur;

public Nombre(int min, int max){this.VALEUR_MIN = this.valeur = min;this.VALEUR_MAX = max;

}

public void inc(){if(valeur < VALEUR_MAX){

this.valeur++;setChanged();notifyObservers();

}}

public void dec(){ // idem -- …… getValeur() + setValeur(…) + toString()

MVC_Swing_JSF11

La Vue est une JFrame et implémente Observer

public class Vue1 extends JFrame implements Observer{

private JButton plus;private JButton moins;private JTextField valeur;private JSlider jauge;

public Vue1(Nombre nombre) {super("Vue1 Nombre");nombre.addObserver(this);

// Mise en place des composants graphiques

pack();setVisible(true);

}

en quelques lignes …, un arbre instance du composite

MVC_Swing_JSF12

La Vue implémente java.util.Observer

@Overridepublic void update(Observable obs, Object arg){if(obs instanceof Nombre){

Nombre n = (Nombre)obs;this.valeur.setText(n.toString());this.jauge.setValue(n.getValeur());

} }

// accesseurspublic JButton getPlus(){return plus;}public JButton getMoins(){return moins;}

}

MVC_Swing_JSF13

Le Contrôle implémente les XXXXListener

public class ControleVue1{private Nombre nombre;

public ControleVue1(Nombre nombre, Vue1 vue){this.nombre = nombre;vue.getMoins(). addActionListener(

new ActionListener(){public void actionPerformed(ActionEvent ae){

ControleVue1.this.nombre.dec();}

});

vue.getPlus(). addActionListener( new ActionListener(){

public void actionPerformed(ActionEvent ae){ControleVue1.this.nombre.inc();

}});

}} adéquation actions de l’utilisateur / opérations su r le modèle

MVC_Swing_JSF14

Démonstration

• Démonstration

• MVC pourquoi faire ?

– Paradigme au-delà de la maturité ?• L’original en 1978 http://heim.ifi.uio.no/~trygver/themes/mvc/mvc-inde x.html

Donner l’illusion à l’utilisateur de manipuler les données du modèle

MVC_Swing_JSF15

Une nouvelle vue, un nouveau contrôle, critiques

public class MainNombreMVC{

public static void main(String[] args){Nombre nombre = new Nombre(0,10); // le modèle

Vue1 vue1 = new Vue1(nombre); ControleVue1 controle1 = new ControleVue1(nombre, v ue1);

Vue2 vue2 = new Vue2(nombre); ControleVue2 controle2 = new ControleVue2(nombre, v ue2);

}}

l’utilisateur peut maintenant modifier la valeur … ajout d’un observateur auprès d’un JTextField

soit jTextField.addActionListener…

MVC_Swing_JSF16

La classe Vue2, est un observateurpublic class Vue2 extends JFrame implements Observer {

private JTextField valeur;private JSlider jauge;

public Vue2(Nombre nombre) {super("Vue2 Nombre");nombre.addObserver(this);Container content = getContentPane();

}

public void update(Observable obs, Object arg){if(obs instanceof Nombre){ // instanceof prévention …

Nombre n = (Nombre)obs;this.valeur.setText(n.toString());this.jauge.setValue(n.getValeur());

} }public JTextField getValeur(){return valeur;}}

en quelques lignes …

MVC_Swing_JSF17

Le Contrôle2 de la vue 2, implements XXXXListener

public class ControleVue2{private Nombre nombre;private Vue2 vue2;

public ControleVue2(Nombre nombre, Vue2 v){this.nombre = nombre;this.vue2 = v;

vue2.getValeur(). addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent ae){try{

int valeur = Integer.parseInt(vue2.getValeur().getTe xt());ControleVue2.this.nombre.setValeur(valeur);

}catch(NumberFormatException nfe){}

}});

}}

Une nouvelle vue engendre ici une nouvelle classe de contrôle, critiques ?Faire autrement ? mieux ?

MVC_Swing_JSF18

Deux nombres … 4 vues, 4 Contrôles

public class MainNombreMVC{

public static void main(String[] args){Nombre nombre = new Nombre(0,10); // le modèleVue1 vue1 = new Vue1(nombre); ControleVue1 controle1 = new ControleVue1(nombre, v ue1);Vue2 vue2 = new Vue2(nombre); ControleVue2 controle2 = new ControleVue2(nombre, v ue2);Vue1 vue11 = new Vue1(nombre);ControleVue1 controle11 = new ControleVue1(nombre, vue11);

Nombre nombreBis = new Nombre(0,100); Vue1 vueBis = new Vue1(nombreBis); ControleVue1 controle = new ControleVue1(nombreBis, vueBis);

}}

Démonstration …

Un dernier exemple : deux nombres … 8 vues, 25 Contrôles, non merci

MVC_Swing_JSF19

Discussion / l’exemple

• Remarquons que : View Selection– Est absent de l’exemple

MVC_Swing_JSF20

Discussion sur l’implémentation du Modèle

• public class Nombre …

• Le Modèle est une classe– Cette classe hérite de java.util.Observable sur cet exemple

• Ce modèle peut devenir un composant logiciel– Un JavaBean

– Peu de différences à part quelques règles d’écritur es• Ces règles permettront une utilisation de ce compos ant par des outils,• Vers une meilleure réutilisation ?• Vers une industrie du composant logiciels ?

– EJB ? Enterprise JavaBeans

» Un nouveau langage au dessus de Java?

MVC_Swing_JSF21

Observable/Observer à la mode JavaBeans

• Paquetage java.beans

• Champs d’instance– int valeur comme property

• Observer comme PropertyChangeListener– public void update (Observable obs, Object o)comme– public void propertyChange (PropertyChangeEvent evt)

• Observable comme PropertyChangeSupport– void notifyObservers (Object o)comme– void firePropertyChange (String property,Object oldValue,Object newValue)

MVC_Swing_JSF22

Un bean

• Un Bean est avant tout une classe …– Un bean est un (extends) POJO, une classe quelconque

Avec

• Le respect de certaines conventions• implements Serializable• Un constructeur par défaut• Un getter et/ou un setter pour chaque variable d’instance• firePropertyChange au sein du setter

• Simple n’est-ce pas ?

• La suite– Nombre devient Bean– La BeanBox, l’outil d’assemblage de Beans : un outil historique– Introspection systématique

MVC_Swing_JSF23

La classe Nombre devient Bean : NombreBeanpublic class NombreBean implements Serializable {

public final int VALEUR_MIN;public final int VALEUR_MAX;private int valeur;private PropertyChangeSupport propertySupport;

public NombreBean(){this.VALEUR_MIN = this.valeur = 0;this.VALEUR_MAX = 10;this.propertySupport = new PropertyChangeSupport(thi s);

}

public void inc(){if(valeur < VALEUR_MAX){

int old = valeur;this.valeur++;propertySupport.firePropertyChange("valeur",old,val eur);

}}

public void addPropertyChangeListener(PropertyChange Listener l) {propertySupport.addPropertyChangeListener(l);

}// public int getValeur() et setValeur()

MVC_Swing_JSF24

La Vue est à l’écoute de son Bean

public class Vue1Bean extends JFrame implements PropertyChangeListener{

private JButton plus;private JButton moins;private JTextField valeur;private JSlider jauge;

public Vue1Bean(NombreBean nombre) {super("Vue1 Nombre");nombre.addPropertyChangeListener(this);

// Le dessin ici}

@Overridepublic void propertyChange(PropertyChangeEvent evt){

assert evt.getPropertyName().equals("valeur");this.valeur.setText(evt.getNewValue().toString());this.jauge.setValue((Integer)evt.getNewValue());

}

Les contrôles ne changent pas, le MVC reste en l’ét at

MVC_Swing_JSF25

NombreBean intègre la BeanBox

• Ajout par l’outil BeanBox d’un listener (EventMonitor ) à chaque changement de valeur de valeur …

démonstration pour l’histoire c’est un outil du siè cle dernier

Usage de l’introspection

setValeurgetValeur

MVC_Swing_JSF26

Usage de l’introspection

Affecter la propriété d’un bean

Object obj une instanceString name le nom de la propriétéint value la nouvelle valeur

public void setProperty(Object obj, String name, int v alue) { String prop = Character.toUpperCase(name.charAt(0)) + name.substring(1);

String mname = "set" + prop;

Class[] types = new Class[] { int.class };

Method method = obj.getClass().getMethod(mname, types );

method.invoke(obj, new Object[] { value });

}

MVC_Swing_JSF27

MVC un autre schéma, encore !, tjs d’accord ?

src : Mastering JSF page 6

MVC_Swing_JSF28

Conclusion ? discussion

• MVC au niveau d’une application

• Et Il y a aussi un MVC au niveau de chaque composan t swing

MVC_Swing_JSF29

L’API Swing

• Présentation « déclarative »

• Le package javax.swing

• Les composants graphiques

• Quelques exemples en « direct »

– Avertissement : • Présentation à de l’API Swing « orientée » JSF

MVC_Swing_JSF30

Sommaire

• Evènements, MVC– Usage des patrons

• Observateur, Commande

– Mise en œuvre du Modèle, Vue, Contrôleur– Exemples

• Démonstration

– Le modèle devient un java Bean– MVC d’un composant swing

• L’API Swing // Saut possible en diapositive 62 ou 94– Un descriptif– Exemples

• Démonstration

– Usage des patrons • Composite, stratégie, fabrique …

• JSF présentation– IHM et HTML

• Du swing côté serveur �� de l’HTML côté client

– MVC et Web

MVC_Swing_JSF31

Swing en images, javax.swing

MVC_Swing_JSF32

Le paquetage swing bien nommé

• javax.swingComposants élémentairesMenus, Barre d’outils et

ToolTipsContainers

• javax.swing.beaninfo• javax.swing.beaninfo.images• javax.swing.border• javax.swing.colorchooser• javax.swing.event

• javax.swing.filechooser• javax.swing.plaf • javax.swing.plaf.basic • javax.swing.plaf.metal• javax.swing.plaf.multi• javax.swing.table • javax.swing.text • javax.swing.text.html• javax.swing.tree• javax.swing.undo

MVC_Swing_JSF33

Hiérarchie de classes 1/2, tout est JComponent

• Container– JComponent

• AbstractButton– JButton– JMenuItem

» JCheckBoxMenuItem

» JMenu

» JRadioButtonMenuItem– JToggleButton

» JCheckBox

» JRadioButton

MVC_Swing_JSF34

Hiérarchie 2/2, JComponent suite

• JComponent– JComboBox– JLabel– JList– JMenuBar– JPanel– JPopupMenu– JScrollBar– JScrollPane– JTextComponent

• JTextArea• JTextField

– JPasswordField• JTextPane

– JHTMLPane

MVC_Swing_JSF35

Autres Composants, toujours des JComponent

• JRootPane• JSeparator• JSlider• JSplitPane• JTabbedPane• JTable• JToolBar• JToolTip• JTree• JViewport

• FontChooser• JColorChooser• JDesktopIcon• JDirectoryPane

– JFileChooser

• JImagePreviewer• JInternalFrame• JLayeredPane

– JDesktopPane

• JOptionPane• JProgressBar

MVC_Swing_JSF36

Exemples 1/3, en images

• Menus, Barre d’outils et ToolTips

– JMenuBar– JMenu– JMenuItem– JCheckBoxMenuItem– JRadioButtonMenuItem– JPopupMenu– JToolBar– JToolTip

MVC_Swing_JSF37

Exemples 2/3

• Composants Textes

– JPasswordField– JTextField– JTextArea– JTextPane– JEditorPane

MVC_Swing_JSF38

Exemples 3/3

• Containers

– JOptionPane– JDialog– JTabbedPane– JSplitPane– JScrollPane– JFrame– JInternalFrame– JDesktopPane– JWindow

MVC_Swing_JSF39

Hiérarchie, suite, top-level et les autres

• Les “Top Level containers” et les autres– JDialog , JFrame , JWindow , JApplet , JInternalFrame

• héritent de Window

• Les autres sont des JComponent– Ils sont ajoutés au “ content pane ” d’un “ top level container “ …

MVC_Swing_JSF40

RootPaneContainer

• Pas d’ajout direct au container (top level)– aFrame.add (new Button (“Help”)); � non

• Ajout au “ content pane ” – aJFrame.getContentPane().add ( new Button (“Help”)); � oui

– RootPaneContainer définit la méthode getContentPane• Implétentée par

– public Container getContentPane() { return getRootPane().getContentPane(); }

• Les top-level– JDialog , JFrame , JWindow , JApplet , JInternalFrame

MVC_Swing_JSF41

Un exemple

import javax.swing.JFrame;import javax.swing.JButton;import javax.swing.JLabel;

import java.awt.Container;import java.awt.FlowLayout;import java.awt.Button;

public class FrameTester {public static void main (String args[]) {

JFrame f = new JFrame ("Exemple de JFrame");Container c = f.getContentPane();c.setLayout (new FlowLayout()); // placement des objets (à suivre)

for (int i = 0; i < 5; i++) {c.add (new JButton (Integer.toString(i))); // swingc.add (new Button (Integer.toString(i))); // awt

}c.add (new JLabel ("Swing"));f.setSize (300, 200);f.show();

}}

f.getContentPane();

MVC_Swing_JSF42

ContentPane …

• Le contenu

MVC_Swing_JSF43

Disposition des objets dans un « container »

• LayoutManager– FlowLayout, BorderLayout, GridLayout

• Composite, Strategy deux Patrons ? À suivre …

B u tto n( fro m a w t )

B o rd e rL a y o u t( fro m a w t )

C o m p o n e n t( fro m a w t )

G r i d L a y o u t( fro m a w t )

L a y o u tM a n a g e r2( fro m a w t )

< < In te r fa c e > >

C o n ta i n e r( fro m a w t )

c o m p o n e n t[]

L a y o u tM a n a g e r( fro m a w t )

< < In te r fa c e > >la y o u tM g r

Composite ?

Strategy ?

MVC_Swing_JSF44

Les Layout

• BorderLayout• FlowLayout• GridLayout• CardLayout• ….

MVC_Swing_JSF45

BorderLayout

En 5 zonesBorderLayout.NORTH

BorderLayout.WEST BorderLayout.CENTER, BorderLayout.EAST

BorderLayout.SOUTH

MVC_Swing_JSF46

FlowLayout

• comme ils viennent …

MVC_Swing_JSF47

Grid Layout

En une table

MVC_Swing_JSF48

Un exemple d’IHM : une JApplet

• Deux boutons , un texte , une liste

JApplet

JPanel (ContentPane)

JButton JButton JPanel

JScrollPaneJTextField

JList

MVC_Swing_JSF49

Exemple, Deux boutons, un texte, une liste

// quelques déclarations

JPanel contentPane;

JButton jButton1 = new JButton();

JButton jButton2 = new JButton();

JTree jTree1 = new JTree();

JTextField jTextField1 = new JTextField();

JPanel jPanel1 = new JPanel();

JScrollPane jScrollPane1 = new JScrollPane();

BorderLayout borderLayout1 = new BorderLayout();

MVC_Swing_JSF50

Construction de l’arbre …

contentPane = this.getContentPane(); // this est une JApplet

contentPane.add(jButton1, null);contentPane.add(jButton2, null);contentPane.add(jPanel1, null);

jPanel1.add(jScrollPane1, BorderLayout.CENTER );jPanel1.add(jTextField1, BorderLayout.NORTH );jScrollPane1.getViewport().add(jTree1, null);

MVC_Swing_JSF51

Divers : de JApplet en JFrame

static void run(JApplet applet, int width, int height) {

JFrame frame = new JFrame();frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE );

frame.getContentPane().add(applet);frame.setSize(width, height);

applet.init();applet.start();frame.setVisible(true);

}

L’arbre change de racine …

MVC_Swing_JSF52

Un autre exemple : Un formulaire

public class LoginForm extends JFrame {

public LoginForm() {super("LoginForm");Container contents = getContentPane();

// contents.setLayout(new BorderLayout()); // par d éfaut

contents.add( getLoginPanel (), BorderLayout.CENTER);contents.add( getButtonPanel (), BorderLayout.SOUTH);pack(); setVisible(true);

}

MVC_Swing_JSF53

Le dessin suite ……

public JPanel getLoginPanel() {JPanel panel = new JPanel(new BorderLayout());JPanel labelPanel = new JPanel(new GridLayout(2,0));JLabel userIdLabel = new JLabel("User ID:");labelPanel.add(userIdLabel);JLabel passwordLabel = new JLabel("Password:");labelPanel.add(passwordLabel);panel.add(labelPanel, BorderLayout.WEST);JPanel fieldPanel = new JPanel(new GridLayout(2,0));JTextField userIdField = new JTextField(10);fieldPanel.add(userIdField);JPasswordField passwordField = new JPasswordField(10);fieldPanel.add(passwordField);panel.add(fieldPanel, BorderLayout.CENTER);return panel;

}

public JPanel getButtonPanel() {JPanel panel = new JPanel(new FlowLayout());JButton okButton = new JButton("OK");panel.add(okButton); return panel;

}

MVC_Swing_JSF54

Démonstration

• Un Arbre ?

MVC_Swing_JSF55

Autres composants

• À suivre

• Fenêtres de dialogues– JOptionPane

• Apparence des objets graphiques– Apparence « windows », Metal,– UIManager.setLookAndFeel

MVC_Swing_JSF56

Une autre famille : JOptionPane

MVC_Swing_JSF57

Un exemple

import javax.swing.JOptionPane;

public class JOption{

public static void main(String[] args) {

Object response = JOptionPane.showInputDialog(null, "au choix", "Titre",

JOptionPane.QUESTION_MESSAGE,

null,

new Object[] { "Amandes", "Noisettes", "Noix"}, "No ix");

// response = ( "Amandes" | "Noisettes" | "Noix" | n ull)

}

}

MVC_Swing_JSF58

Au choix

• Lecture bloquante … jusqu’à ce que l’utilisateur

Unification des 3 précédents.showOptionDialog

Une indication.showMessageDialog

Demande un choix (c.f. exemple précédent).showInputDialog

Pose une question oui/non/annuler.showConfirmDialog

DescriptionMéthode

MVC_Swing_JSF59

Les Apparences LookAndFeel

• Choix de l’apparence.

– Metal (par défaut)• UIManager.setLookAndFeel("javax.swing.plaf.metal.Me talLookAndFeel");

– Windows• UIManager.setLookAndFeel("com.sun.java.swing.plaf.w indows.WindowsLookAndFeel");

– Apparence Motif• UIManager.setLookAndFeel("com.sun.java.swing.plaf.m otif.MotifLookAndFeel");

MVC_Swing_JSF60

Apparence Windows

MVC_Swing_JSF61

Apparence Métal (Par Défaut)

MVC_Swing_JSF62

Swing : où sont les patrons ?

• Patron Composite– Construction d’une IHM

• Patron Stratégie– Disposition des objets graphiques

MVC_Swing_JSF63

MVC_Swing_JSF64

Le patron Composite, rappel

• Structures de données récursives– Un Composant est une feuille ou un composite– Un Composite est un Composant

MVC_Swing_JSF65

Le patron Composite et l’API graphique

ContainerJButtonJLabel

Component

MVC_Swing_JSF66

Le formulaire est une instance du composite !

• src : Mastering JSF page 31

MVC_Swing_JSF67

list() comme operation()

• Méthode de la classe Component quelque soit l’arbre

• Component loginForm = new LoginForm ();• loginForm.list();

LoginForm[frame0,0,0,183x103,layout=java.awt.BorderLayout,title=LoginForm,resizable,normal,defaultCloseOperation=HIDE_ON_CLOSE,rootPane=javax.swing.JRootPane[,4,23,175x76,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]

javax.swing.JRootPane[,4,23,175x76,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=]

javax.swing.JPanel[null.glassPane,0,0,175x76,hidden,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777217,maximumSize=,minimumSize=,preferredSize=]

javax.swing.JLayeredPane[null.layeredPane,0,0,175x76,alignmentX=0.0,alignmentY=0.0,border=,flags=0,maximumSize=,minimumSize=,preferredSize=,optimizedDrawingPossible=true]………………

MVC_Swing_JSF68

Retour sur L’original

• Méthode Operation()– Component c = … une feuille ou un composite– C.Operation();

• Notons l’accès aux enfants depuis un nœud composite , classe Component– Méthode getChild

MVC_Swing_JSF69

Le patron Strategy

• Context ctxt = new Context(new ConcreteStrategyB());– Le champ d’instance aStrategy est affecté par l’argument du constructeur

Puis• ctxt.contextInterface();

– Retournera un AlgorithmInterface () concret

MVC_Swing_JSF70

Le patron Strategy et les « layout »

• Exemple :– Container content = getContentPane();– content.setLayout(new BorderLayout());

BorderLayout FlowLayout GridLayout

LayoutManagerContainer

MVC_Swing_JSF71

Les images … (encore un patron), en apparté

• Le chargement d’une image peut-être lent…– Si c’est synchrone alors l’application attend

alors un chargement asynchrone s’impose …

• Pour cela usage– Du paradigme Producteur/Consommateur– Du patron observateur

– Une instance de la classe Image n’est pas un tablea u de pixels mais un canal entre un producteur d’image et son consommate ur

– L’image est un observateur, notifiée par le producteur

MVC_Swing_JSF72

ImageObserver

imageUpdate(img : Image, infoflags : int, x : int, y : int, width : int, height : int) : boolean

<<Interface>>

Image

getWidth(observer : ImageObserver) : intgetHeight(observer : ImageObserver) : intgetSource() : ImageProducergetGraphics() : GraphicsgetProperty(name : String, observer : ImageObserver) : ObjectgetScaledInstance(width : int, height : int, hints : int) : Imageflush() : void

Component

FilteredImageSource MemoryImageSource

ImageProducer

addConsumer(ic : ImageConsumer) : voidisConsumer(ic : ImageConsumer) : booleanremoveConsumer(ic : ImageConsumer) : voidstartProduction(ic : ImageConsumer) : voidrequestTopDownLeftRightResend(ic : ImageConsumer) : void

<<Interface>>

src

ImageConsumer

setDimensions()setProperties()setColorModel()setHints()setPixels()setPixels()imageComplete()

<<Interface>>

0..*0..*

BufferedImage

MVC_Swing_JSF73

Un exemple … Aurores boréales au Cnam ?

public class ImageDemo {static public void main(String args[]) throws Exceptio n {

JFrame f= new JFrame("test images");f.getContentPane().add(new MyPanel());f.setSize(300,200);f.setVisible(true);

}

static class MyPanel extends JPanel {private Image m1,m2;public MyPanel() throws MalformedURLException {

Toolkit toolkit=Toolkit.getDefaultToolkit();m1=toolkit.getImage(new URL("http://www.cnam.fr/image s/logo_cnam.gif"));m2=toolkit.getImage(new

URL("http://media.aftenposten.no/archive/00411/_127 4097_jpg_411307h.jpg"));

}public void paintComponent(Graphics g) {Dimension d = getSize();g.drawImage(m2,0,0,this);g.drawImage(m1,0,0,this);

}}}

MVC_Swing_JSF74

Réagir aux clics : le formulaire déjà vu

• Associer une action au clic sur OK– légitime

• Patron observateur/observé– Les « listeners »

MVC_Swing_JSF75

Patron observé/observateur-écouteur( ou listener)

• 1) enregistrement auprès du bouton d’un écouteur– bouton.addActionListener(ActionListener al)

• Plusieurs écouteurs sont possibles

• 2) A chaque clic les écouteurs sont notifiés– al.actionPerformed(ActionEvent ae)

– L’exemple du formulaire suit …

MVC_Swing_JSF76

le patron Observateur, l’original

• http://www.codeproject.com/gen/design/applyingpatterns/observer.gif

MVC_Swing_JSF77

Ajout d’un observateur du bouton

public JPanel getButtonPanel() {

JPanel panel = new JPanel(new FlowLayout());

JButton okButton = new JButton("OK");

panel.add(okButton);

okButton.addActionListener(new OkButtonAction());

return panel;

}

}

MVC_Swing_JSF78

OkButton action !!!

class OkButtonAction implements ActionListener{

public void actionPerformed(ActionEvent ae){// Vérification du nom et mot de passe// par exemple …

}

}

Différentes formes syntaxiques possiblesClasse interne et statiqueClasse interne et membreClasse anonyme

MVC_Swing_JSF79

Action, Listeners et les autres, par convention

• Un composant swing enregistre ses écouteurs– addXXXXListener

• Les écouteurs implémentent – L’interface XXXXListener et « sont des » java.awt.event.EventListener

– Cette interface décrit une méthode acceptant en par amètre un XXXXEvent– Chaque écouteur s’enregistre auprès du composant sw ing

• A chaque changement d’état du composant swing– Les méthodes des écouteurs pré-enregistrés sont exéc utées

• Le paramètre XXXXEvent contient au moins la source d e la notification

MVC_Swing_JSF80

EventListener et ses descendants

• Héritage au sens des interfaces

MVC_Swing_JSF81

Des Adaptateurs à adapter

• Implémenter un XXXXListener peut être fastidieux– Surtout si une seule méthode de l’interface est con cernée …

– Exemple : l’interface WindowListener• public void windowActivated (WindowEvent e) • public void windowClosed (WindowEvent e) • public void windowClosing (WindowEvent e) • public void windowDeactivated (WindowEvent e) • public void windowDeiconified (WindowEvent e) • public void windowIconified (WindowEvent e) • public void windowOpened (WindowEvent e)

– Au total 7 méthodes à implémenter …

• Utile : il existe une classe XXXXAdapter qui impléme nte XXXXListener

– Exemple la classe WindowAdapter

MVC_Swing_JSF82

XXXXAdapter à adapter

• Exemple suite : WindowAdapter– Au clic dans la case de fermeture alors arrêt bruta l du programme– Pas d’action pour les 6 autres méthodes….

Window w = …

w.addWindowListener( new WindowAdapter(){

public void windowClosing(WindowEvent event) { System.exit(0);

}});

MVC_Swing_JSF83

Swing, un constat

C’est une première présentation

• Des composants graphiques• Une gestion des évènements• Un look and feel indépendant

• IHM alors MVC– Modèle Vue Contrôleur

– Comment ?, quel déploiement ?, pourquoi faire ?

MVC_Swing_JSF84

Conclusion, discussion

• MVC– Mature

La suite

• MVC et composant swing– Certains composants proposent de changer le modèle et l’IHM…

• Saut possible en 95

MVC_Swing_JSF85

Un Composant Swing et MVC

• Par exemple– JTextField

• Une zone de texte (classe JTextComponent)

– Le Modèle• Le texte (classe PlainDocument)

– L’interface Utilisateur• Un rectangle (classe BasicTextFieldUI )

• En standard– JTextField field = new JTextField();

• Avec un autre modèle– JTextField field = new JTextField (new unAutreModèleDe Document());

• Avec une autre interface utilisateur (vue)– field.setUI(new uneAutreInterface());

MVC_Swing_JSF86

Un exemple, avec démo possible…

• Le « nouveau » JTextField ne peut contenir que des maju scules !– Une contrainte sur une entrée du formulaire

– Un nouveau modèle, ici une sous-classe de Document– this.userIdField = new JTextField(new UnAutreModèleDeTexte(), "", 10);

public class UnAutreModèleDeTexte extends PlainDocume nt {public void insertString(int offs, String str, Attrib uteSet a)

throws BadLocationException {if (str == null) {

return;}char[] upper = str.toCharArray();for (int i = 0; i < upper.length; i++) {

upper[i] = Character.toUpperCase(upper[i]);}super.insertString(offs, new String(upper), a);

}}

MVC_Swing_JSF87

Donc nous avons MVC et SMA…

• SMA : Separable Model Architecture

• ou bien

MVC_Swing_JSF88

Envoi d’un événement lors d’un changement d’état

Lecture de l’état du modèle

SMA

MVC_Swing_JSF89

Component Model Interface Model Type

JButton ButtonModel GUI

JToggleButton ButtonModel GUI/data

JCheckBox ButtonModel GUI/data

JRadioButton ButtonModel GUI/data

JMenu ButtonModel GUI

JMenuItem ButtonModel GUI

JCheckBoxMenuItem ButtonModel GUI/data

JRadioButtonMenuItem ButtonModel GUI/data

JComboBox ComboBoxModel data

JProgressBar BoundedRangeModel GUI/data

JScrollBar BoundedRangeModel GUI/data

JSlider BoundedRangeModel GUI/data

JTabbedPane SingleSelectionModel GUI

JList ListModel data

JList ListSelectionModel GUI

JTable TableModel data

JTable TableColumnModel GUI

JTree TreeModel data

JTree TreeSelectionModel GUI

JEditorPane Document data

JTextPane Document data

JTextArea Document data

JTextField Document data

JPasswordField Document data

MVC_Swing_JSF90

« Model » et Notification…Model Listener Event

ListModel ListDataListener ListDataEvent

ListSelectionModel ListSelectionListener ListSelectionEvent

ComboBoxModel ListDataListener ListDataEvent

TreeModel TreeModelListener TreeModelEvent

TreeSelectionModel TreeSelectionListener TreeSelectionEvent

TableModel TableModelListener TableModelEvent

TableColumnModel TableColumnModel-

Listener

TableColumnModel-

Event

Document DocumentListener DocumentEvent

Document UndoableEditListener UndoableEditEvent

MVC_Swing_JSF91

Jlist and ListModel…exemple fourni.. À suivre

MVC_Swing_JSF92

JL ist

JList()setC ellRenderer()setModel()

JC om ponentC om ponentU I

# ui

L istU I

ListD ataEvent

getType()getIndex0()getIndex1()ListD ataEvent()

BasicListUI

# list

ListModel

g etS ize ()g etE le me ntAt()a dd ListD a taL istene r()rem oveL istD ata Liste ner()

<<Interface>>

-da taM od el

AbstractListM odel

addListD ataListener(l : L istD ataListener) : voidremoveListD ataListener(l : L istD ataListener) : voidfireC ontentsC hanged(source : Object, index0 : int, index1 : int) : voidfireIntervalAdded(source : Object, index0 : int, index1 : int) : voidfireIntervalRemoved(source : Object, index0 : int, index1 : int) : voidgetListeners(listenerType : C lass) : EventListener[]

L istD ataListener

intervalAdded(e : L istD ataEvent) : voidintervalRemoved(e : L istD ataEvent) : voidcontentsC hanged(e : L istD ataEvent) : void

<<Interface>>

#listD ataListener

0..*0..*

MVC_Swing_JSF93

ListD ataListener<<Interface>>

TableModelEventD ELETE : int = - 1INSERT : int = 1UPD ATE : int = 0

getC olumn()getF irstRow()getLastRow()getType()

Tab le Mo de l

getRowC ount()getC olumnC ount()getC olumnName()getC olumnC lass()isC ellEditable()getValueA t()setValueA t()addTableModelListener()removeTableModelListener()

<<Interface>>

AbstractTableM odel

getC olumnName(column : int) : S tringfindC olumn(columnName : S tring) : intgetC olumnC lass(columnIndex : int) : C lassisC ellEditable(rowIndex : int, columnIndex : int) : booleansetValueA t(aValue : Object, rowIndex : int, columnIndex : int) : voidaddTableModelListener(l : TableModelListener) : voidremoveTableModelListener(l : TableModelListener) : voidfireTableD ataC hanged() : voidfireTableS tructureC hanged() : voidfireTableRowsInserted(firstRow : int, lastRow : int) : voidfireTableRowsUpdated(firstRow : int, lastRow : int) : voidfireTableRowsD eleted(firstRow : int, lastRow : int) : voidfireTableC ellUpdated(row : int, column : int) : voidfireTableC hanged(e : TableModelEvent) : voidgetListeners(listenerType : C lass) : EventListener[]

TableModelListener

ta bleC ha nged(e : TableModelEvent) : void

<<Interface>>

0..*0..*

TableU I

JC o m po ne nt

C o m po ne ntU I#ui

BasicTableUI

JTable#dataModel#table

MVC_Swing_JSF94

Sommaire

• Evènements, MVC– Usage des patrons

• Observateur, Commande

– Mise en œuvre du Modèle, Vue, Contrôleur– Exemples

• Démonstration

– Le modèle devient un java Bean– MVC d’un composant swing

• L’API Swing– Un descriptif– Exemples

• Démonstration

– Usage des patrons • Composite, stratégie, fabrique …

• JSF présentation– IHM et HTML

• Du swing côté serveur �� de l’HTML côté client

– MVC et Web

MVC_Swing_JSF95

JSF une introduction

• MVC Web

• JSF – Framework pour applications web– MVC web– Configuration en fichier xml– Mise en place d’un JavaBean adaptateur si nécessaire

MVC_Swing_JSF96

bibliographie

• Mastering JavaServer Faces, 2004 ed Wiley– Bill Dudney,Jonathan Lehr, Bill Willis, LeRoy Mattingly

– La plupart des figures présentes sur ce support sont extraites de ce livre• src : mastering JSF

• Cours de J-L Dewez GLG203/2009

– La plupart des transparents qui suivent sont extraits de ce support

MVC_Swing_JSF97

Evolution des Frameworks

• Servlets - 1997• Procedural JSP - 1999• Composition Frameworks

– Tapestry– 2000

• Action Frameworks– Struts– 2001

• Component Frameworks– JavaServer™ Faces– 2004

MVC_Swing_JSF98

Evolution de l' Architecture Web

1. Modèle 1 (orienté Pages web)

2. Modèle 2 (orienté Servlette de contrôle)

Les frameworks WebStrutsJavaServer Faces comme un standard

MVC_Swing_JSF99

Modèle 1 Orienté page

<html> <head> <script type="text/javascript">

function validate_required(field,alerttxt) {

with (field) { if (value==null||value=="") {alert(alerttxt);return false}

else {return true} } }

function validate_form(thisform) {

with (thisform) { if (validate_required(email,"Email must be filledout!")==false) {email.focus();return false} } }

</script> </head>

<body>

<form action="submitpage.htm" onsubmit="return validate_form(this)"method="post">

Email: <input type="text" name="email" size="30">

<input type="submit" value="Submit">

</form>

</body> </html>

MVC_Swing_JSF100

Modèle 2 Architecture (Orienté Servlette)

Servlet

JSP JavaBeans

Nav

igat

eur

MVC_Swing_JSF101

Pattern MVC et le Web

MVC_Swing_JSF102

web MVC, JSP

• Le contrôleur est une servlette, la vue « du JSP »

MVC_Swing_JSF103

Un autre dessin, vision couches

• Les JavaBeans sont bien de retour…

MVC_Swing_JSF104

Web MVC et Struts

MVC_Swing_JSF105

JSF et swing ?

• Une pensée en jargon swing :– Un JFrame , son contentPane dans lequel la disposition est un

GridLayout , deux JButton, deux JLabel deux JTextField , …

MVC_Swing_JSF106

Exprimée en JSF !, un nouveau langage ?

<f:view><h:form id=”customerForm” >

<h:panelGrid columns=”2”><f:facet name=”header”>

<h:panelGroup><h:outputText id=”header” value=”Customer Name”/>

</h:panelGroup></f:facet><h:panelGroup>

<h:outputText id=”fNameLabel” value=”First Name:”/><h:inputText id=”fName” value=”#{customer.firstName}”/>

</h:panelGroup><h:panelGroup>

<h:outputText id=”lNameLabel” value=”Last Name:”/><h:inputText id=”lName” value=”#{customer.lastName}”/>

</h:panelGroup><h:panelGroup>

<h:commandButton id=”cancel” value=”Cancel”/><h:commandButton id=”save” value=”Save”/>

</h:panelGroup></h:panelGrid>

</h:form></f:view>

MVC_Swing_JSF107

JSF Le principe

• Mastering JSF page 19

MVC_Swing_JSF108

Contrôleur, principe

• Réception des requêtes des clients– FacesServlet

• Configuration• Étapes pour la réponse

1. Restitution de la page1. Si celle-ci a déjà été présentée au client

2. Mise à jour de l’interface (côté serveur)3. Validation, tests des entrées4. Mise à jour du modèle5. Application invoquée

• Interaction avec le JavaBean, EJB,…

6. Construction de la réponse• JSP-View

MVC_Swing_JSF109

Le Modèle, ici un Bean

public final class LoginBean implements Serializable{private String password ;private String userId ;

public String get Password () {return (this.password);}public void set Password (String password) {

this.password = password;}public String get UserId () {return (this.userId);}public void set UserId (String userId) {

this.userId = userId;}public String login() { // success ou failure

if(isValide()) // consultation d’une table …return "success";

elsereturn "failure";

}}

MVC_Swing_JSF110

Contrôleur / config

• Comment appeler le LoginBean ?– Notamment la méthode login ?

• Extrait du faces-config.xml– Installation du Bean, des accesseurs…

<managed-bean><managed-bean-name> login </managed-bean-name><managed-bean-class> LoginBean </managed-bean-class><managed-bean-scope>request</managed-bean-scope><managed-property>

<property-name> userId </property-name></managed-property><managed-property>

<property-name> password </property-name></managed-property>

</managed-bean>

MVC_Swing_JSF111

config

<managed-bean>// le nom pour JSF<managed-bean-name> login </managed-bean-name>// la classe Java<managed-bean-class> LoginBean </managed-bean-class>// portée de cet objet, session , application , request// session une instance par utilisateur// application une seule instance// request une instance par requête<managed-bean-scope>request</managed-bean-scope>// accès aux champs d’instance<managed-property>

<property-name> userId </property-name></managed-property>…

</managed-bean>

MVC_Swing_JSF112

Contrôleur / config / navigation / Vue

• Quel enchaînement des pages souhaité ?– La page login.jsp comme accueil– soit la page home.jsp en cas de succès, success– soit la même page login.jsp si échec, failure

• Extrait du faces-config.xml– Un diagramme d’états

<navigation-rule><from-view-id>/login.jsp</from-view-id>

<navigation-case><from-out-come> sucess </from-out-come>

<to-view-id> /home.jsp </to-view-id></navigation-case>

<navigation-case><from-out-come> failure </from-out-come>

<to-view-id> /login.jsp </to-view-id></navigation-case>

</navigation-rule>

MVC_Swing_JSF113

Le formulaire /login.jsp

<html><head><meta http-equiv=”Content-Type” content=”text/html; charset=iso-8859-1”><title>Login</title>

<%@ taglib uri=”http://java.sun.com/jsf/core/” prefi x=” f ” %><%@ taglib uri=”http://java.sun.com/jsf/html” prefix =” h” %>

</head><body>Log in with your User ID and Password.<br/><br/><f:view><h:form>

<h:outputLabel for=”userId”><h:outputText value=”User ID”/>

</h:outputLabel><h:inputText id=”userId” value=” #{login.userId} ”/><br/><h:outputLabel for=”password”>

<h:outputText value=”Password”/></h:outputLabel><h:inputSecret id=”password” value=” #{login.password} ”/><br/><h:commandButton action=” #{login.login} ” value=”Login”/>

</h:form></f:view></body></html>

Usage deschampsuserIdpassword

La méthode loginCelle-ci retourne une « String »

MVC_Swing_JSF114

IHM-JSF en HTML pour le client

un extrait de login.jsp

<%@ taglib uri=”http://java.sun.com/jsf/html” prefix =” h” %>

c.f. page précédente

<h:inputSecret id=”password” value=” #{login.password} ”/><br/>

• Le client reçoit un texte « de l’HTML »<input id="form:password" name="form:password" type="password" />

Notons que :Côté client ce sont des String …

MVC_Swing_JSF115

Un formulaire HTML / Composite JSF

• Un formulaire HTML est présenté au client

• Côté serveur un composite apparenté swing– est créé– Ou est restauré

– Une instance d’un Composite ?

MVC_Swing_JSF116

Le composite JSF

• Pas de top-level, encore plus simple donc…

MVC_Swing_JSF117

Le formulaire devient en interne…

• Mais quels sont ces composants ?• Validation des entrées ?• Appel du Bean (managed_bean) ?• Et les évènements ? • Avons-nous accès à cette structure ?

– À suivre….

MVC_Swing_JSF118

du swing ?

MVC_Swing_JSF119

Input

MVC_Swing_JSF120

Action et liens

MVC_Swing_JSF121

Output

• Un exemple

MVC_Swing_JSF122

Les tags JSF

MVC_Swing_JSF123

Les tags de boutons

MVC_Swing_JSF124

liens

MVC_Swing_JSF125

sélection

MVC_Swing_JSF126

Pause JSF nouveau langage génération de pages HTML ?

• <%@ taglib uri="http://java.sun.com/jsf/html" prefi x="h"%><%@ taglib uri="http://java.sun.com/jsf/core" prefix ="f"%>

<f:view><html>

<body><h:form>

<h:panelGrid columns="3" border="1" rules="all" titl e="This ispanelGrid demo">

<f:facet name="header"><h:outputText value="Fill Numbers Below"/>

</f:facet><h:inputText/><h:inputText/><h:inputText/><h:inputText/><h:inputText/><h:inputText/><h:inputText/><h:inputText/>

</h:panelGrid></h:form>

</body></html>

</f:view>

• src : http://www.roseindia.net/jsf/panelGrid.shtml• f:facet vu ensuite

MVC_Swing_JSF127

En HTML, c’est ce que comprend le client

• <html><body>

<form id="_id0" method="post"enctype="application/x-w ww-form-urlencoded"><table border="1" rules="all" title="This is panelGrid d emo"><thead><tr><th colspan="3" scope="colgroup">Fill Numbers Below </th></tr></thead><tbody><tr><td><input type="text" name="_id0:_id3" /></td><td><input type="text" name="_id0:_id4" /></td><td><input type="text" name="_id0:_id5" /></td></tr><tr><td><input type="text" name="_id0:_id6" /></td><td><input type="text" name="_id0:_id7" /></td><td><input type="text" name="_id0:_id8" /></td></tr><tr><td><input type="text" name="_id0:_id9" /></td><td><input type="text" name="_id0:_id10" /></td></tr></tbody></table>

<input type="hidden" name="_id0" value="_id0" /></form></body>

</html>

MVC_Swing_JSF128

Composite le retour

MVC_Swing_JSF129

Conclusion

• MVC

• Swing et MVC

• JSF/Swing et MVC Web