際際滷

際際滷Share a Scribd company logo
Il framework Wicket Andrea Del Bene Jug Marche [email_address]
Quali sono i guai della programmazione web? Le tecnologie su cui si basa il web si basano su paradigmi molto diversi da quelli dei linguaggi di programmazione moderni (OOP in primis).  Quando scegliamo le pagine web come GUI dobbiamo affrontare  due grossi limiti  di questa tecnologia: Le pagine (le  viste  del programma) sono dei semplici file di testo da spedire al browser e non possono essere rappresentate ed usate con gli strumenti dell'OOP
L'HTTP 竪  stateless  e dobbiamo fare i salti mortali per associare uno stato alla navigazione di un utente sul nostro sito (di solito si ricorre all'oggetto Session)
Wicket: pagine come oggetto Wicket 竪 un framework a componenti per lo sviluppo di soluzioni web Java che propone una soluzione ad entrambi i problemi visti A differenza di altre soluzioni (JSP, Struts, Spring MVC, ecc...) le pagine web sono trattate come vere e proprie istanze di oggetto (classe  WebPage ). Non dobbiamo pi湛 usare direttamente Request e Response nel nostro codice e l'HTML  竪 usato solo come template di visualizzazione, non contiene n竪 taglib n竪 codice java. Come vedremo trattare le pagine come oggetti offre una soluzione  trasparente  anche al problema della conservazione dello stato... Per fare ci嘆 Wicket offre una gerarchia di classi molto simile a quella proposta da  Swing  per realizzare le GUI di applicazioni desktop
Wicket VS Swing In Wicket ogni entit 竪 un componente e la pagina (la classe WebPage) contiene a sua volta istanze di componenti.  WebPage ha una funzione analoga alla classe JWindow (o JFrame) in Swing.
Dov'竪 finito l'HTML? Se la pagina per lo sviluppatore 竪 una classe Java come ottengo l'HTML finale da inviare al Browser? In Wicket la classe che rappresenta una pagina ha associata una pagina HTML standard che funziona da  template  e che per default deve trovarsi  nella stessa cartella  della classe ed avere  lo stesso nome .  La classe Wicket pu嘆 mappare i suoi componenti interni con i tag presenti nella pagina HTML. Wicket offre un set di componenti con cui mappare i vari elementi di una pagina HTML ( paragrafi <p>, form, div, span, controlli di input, ecc...)
Il file web.xml E' il momento di vedere un primo esempio di utilizzo di Wicket. L'applicazione 竪 una classica  web application  Java. Il file web.xml deve dichiarare un elemento  <filter>   che istanzi una sottoclasse di  org.apache.wicket.protocol.http.WebApplication  (nel nostro caso la classe  helloWorld.WicketApplication ).  <? xml   version = &quot;1.0&quot;   encoding = &quot;UTF-8&quot; ?> <! DOCTYPE   web-app PUBLIC   &quot;-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN&quot; &quot;http://java.sun.com/dtd/web-app_2_3.dtd&quot; > < web-app > < display-name > Wicket  HelloWorld </ display-name > < filter > < filter-name > WizardApplication </ filter-name > < filter-class > org.apache.wicket.protocol.http.WicketFilter </ filter-class > < init-param > < param-name > applicationClassName </ param-name > < param-value > helloWorld.WicketApplication </ param-value > </ init-param > </ filter > < filter-mapping > < filter-name > WizardApplication </ filter-name > < url-pattern > /* </ url-pattern > </ filter-mapping > </ web-app >
La classe WicketApplication package  helloWorld; import  org.apache.wicket.Page; import  org.apache.wicket.protocol.http.WebApplication; public   class  WicketApplication  extends  WebApplication { @Override public  Class<?  extends  Page> getHomePage() { return  HomePage. class ; } } La classe WicketApplication oltre ad essere il cardine dell'applicazione Wicket, pu嘆 sovrascrivere numerosi metodi della classe madre per customizzare il comportamento della nostra applicazione.  Sovrascrivendo la funzione  getHomePage  si pu嘆 specificare la pagina home page della nostra applicazione (HomePage nel nostro caso).
Pagina HelloWorld  La mappatura tra elementi HTML ed oggetti Java avviene aggiungendo al tag l'attributo wicket:id=  < html > < head > < meta   http-equiv = &quot;Content-Type&quot;   content = &quot;text/html; charset=UTF-8&quot; > < title > Insert title here </ title > </ head > < body > < h1   wicket:id = &quot;label&quot; ></ h1 > </ body > </ html > Nella classe della pagina Wicket bisogna aggiungere un componente con id uguale al wicket:id dell'elemento che si vuole mappare. package  helloWorld; import  org.apache.wicket.markup.html.WebPage; import  org.apache.wicket.markup.html.basic.Label; public   class  HomePage  extends  WebPage { public  HomePage(){ super (); add( new  Label( &quot;label&quot; ,  &quot;Hello World&quot; )); } } HelloWorld.html HelloWorld.java
WicketHelloWorld Nel tag <h1> 竪 stato inserito il testo fornito come secondo parametro nel costruttore del componente Label. ... < body > < h1   wicket:id = &quot;label&quot; ></ h1 > </ body > ... ... public  HomePage(){ super (); add( new  Label( &quot;label&quot; ,  &quot;Hello World&quot; )); } ...
Wicket come template per layout L'esempio appena visto usa in maniera molto primitiva la capacit di Wicket di manipolare il contenuto di una pagina HTML usando codice Java. Questa tecnica pu嘆 essere usata per creare il layout grafico delle nostre pagine usando un numero arbitrario di  wicket:id  nella nostra pagina ed inniettando il codice HTML dei vari elementi che la compongono (ad esempio: l'header, il men湛 di navigazione, il footer, il contenuto, ecc...) Per fare ci嘆 useremo l'oggetto  Panel  di Wicket che permette di associare il contenuto di una pagina HTML ad un componente custom di Wicket e poterlo aggiungere in una pagina del framework.
Il framework Wicket Il layout con Wicket
Layout di una pagina web Ora vogliamo espandere quanto visto nell'esempio precedente per creare un classico layout per le pagine del nostro sito: un header, un men湛 di sinistra, il contenuto centrale ed un footer conclusivo. Header Men湛 Contenuto Footer
L'approccio classico Di solito per conferire alle pagine un layout stabilito ci si affida a tecnologie di templating  server side  che caricano i vari pezzi della pagina prima di spedirla al browser. <%@include file=&quot;../common/Jug4TendaHeader.jsp&quot;%> <%@include file= &quot;gestioneOspiteMenu.htm &quot;%> <div id=&quot;Content&quot;> <%@include file=&quot;../common/Jug4TendaFooter.jsp&quot;%>
Layout in Wicket Con Wicket possiamo creare una pagina di template principale (chiamiamola Jug4TendaTemplate) suddivisa nei componenti desiderati, ognuno rappresentato da un <div> e con il proprio wicket:id <div wicket:id=headerPanel></div> <div wicket:id=menuPanel> </div> <div wicket:id=contentPanel></div> <div wicket:id=footerPanel></div>
I pannelli di Wicket I pannelli sono lo strumento con cui possiamo creare componenti personalizzati. Di fatto sono  quasi  come le pagine Wicket vere e proprio in quanto anche i pannelli: Sono associati a pagine HTML (pagine HTML  complete !)
Possono a loro volta contenere altri componenti A differenza delle pagine per嘆 i pannelli non possono essere rendereizzati  stand alone , ma devono essere inseriti in una pagina web I pannelli sono gli strumenti ideali per suddividere la pagina nei sui componenti grafici e per poterli riutilizzare in pi湛 pagine.
Il pannello header < html > < head > < meta   http-equiv = &quot;Content-Type&quot;   content = &quot;text/html; charset=UTF-8&quot; > < title > Insert title here </ title > </ head > < body > <wicket:panel> < table   width = &quot;100%&quot;   style = &quot;border: 0px none;&quot; > < tbody >< tr > < td >< img   alt = &quot;Jug4Tenda&quot;   src = /slideshow/presentazione-wicket/6504675/&quot;wicketLayout_files/logo_jug4tenda.gif&quot; ></ td > < td >< h1 > Gestione   Anagrafica   Accoglienze </ h1 ></ td > < td >< img   alt = &quot;Associazione di volontariato La Tenda d'Abramo&quot;   src = &quot;wicketLayout_files/logo_latendadabramo.gif&quot; ></ td > </ tr > </ tbody > </ table > </wicket:panel> </ body > </ html >  HeaderPanel.html La pagina HTML di un pannello deve avere il tag  <wicket:panel>  all'interno del quale si trova l'HTML del pannello stesso.
La classe del pannello header package  helloWorld.layoutTenda; import  org.apache.wicket.markup.html.panel.Panel; public   class   HeaderPanel   extends  Panel { public  HeaderPanel(String id) { super (id); } }  HeaderPanel.java La classe di un pannello Wicket deve avere almeno un costruttore che richiama il costruttore padre passandogli il wicket id come parametro stringa. Anche i pannelli cos狸 come le pagine devono avere la classe e il file HTML nella stessa cartella e devono avere lo stesso nome.
Il pannello footer  < wicket:panel > < span   class = &quot;piccolo&quot; > Powered by  </ span > < a   target = &quot;_blank&quot;   title = &quot;vai al sito dello JUG Ancona,..   href = &quot;http://www.jugancona.it/&quot; > < img   title = &quot;vai al sito dello JUG Ancona, ...&quot;   alt = &quot;JUG Ancona, Java User    Group di Ancona&quot;   src = /slideshow/presentazione-wicket/6504675/&quot;wicketLayout_files/logo_jugancona.gif&quot; ></ a > < img   title = &quot;JUG, Java User Group&quot;   alt = &quot;JUG, Java User Group&quot;     src = &quot;wicketLayout_files/logo_jug.gif&quot; > < a   title = &quot;vai al sito del framework Spring &quot;   href = &quot;http://www.springframework.org/&quot; > < img   title = &quot;vai al sito del framework Spring&quot;   alt = &quot;Spring&quot;   src = &quot;wicketLayout_files/logo_spring.gif&quot; ></ a > < a   title = &quot;vai al sito di Mozilla Firefox...&quot; href = &quot;http://www.mozilla.com/&quot; > < img   title = &quot;vai al sito di Mozilla Firefox...&quot;   alt = &quot;Firefox&quot;  src = &quot;wicketLayout_files/logo_firefox.gif&quot; ></ a > </ wicket:panel >   FooterPanel.html package  helloWorld.layoutTenda; import  org.apache.wicket.markup.html.panel.Panel; public   class   FooterPanel   extends  Panel { public  FooterPanel(String id) { super (id); } }  HeaderPanel.java
Il pannello menu  <div class=&quot;menuTitle&quot;>Menu principale</div> <ul class=&quot;menuItems&quot;> <li> <img src=/slideshow/presentazione-wicket/6504675/&quot;wicketLayout_files/home.gif&quot;> <a class=&quot;Offmouse&quot; href=&quot;http://localhost:8080/jug4tenda/index.jsp&quot;  id=&quot;newOspite&quot; onmouseout=&quot;this.className='Offmouse'&quot;  onmouseover=&quot;this.className='Onmouse'&quot;>Home</a></li> </ul>   MenuPanel.html package  helloWorld.layoutTenda; import  org.apache.wicket.markup.html.panel.Panel; public   class  Menu Panel   extends  Panel { public  Menu Panel (String id) { super (id); } }  MenuPanel.java
La pagina template Jug4Wicket  package  helloWorld.layoutTenda; import  org.apache.wicket.markup.html.WebPage; public   class   JugTemplate   extends  WebPage { public  JugTemplate(){ add( new   HeaderPanel( &quot;headerPanel&quot; ) ); add( new   MenuPanel( &quot;menuPanel&quot; ) ); add( new   FooterPanel( &quot;footerPanel&quot; ) ); add( new   Label( &quot;contentComponent&quot;, &quot;content&quot; ) ); } } < html > < head > < meta   http-equiv = &quot;Content-Type&quot;   content = &quot;text/html; charset=UTF-8&quot; > < title > Jug4Tenda - Home page </ title > ...   </ head > < body > < div   id = &quot;intestazione&quot;   wicket:id = &quot;headerPanel&quot; > intestazione </ div > < div   id = &quot;pagina&quot; > < div   id = &quot;Menu&quot;   wicket:id = &quot;menuPanel&quot; > Menu </ div > < div   id = &quot;Content&quot;  wicket:id = &quot;content&quot; > Content </ div > </ div > < div   id = &quot;piedipagina&quot;   wicket:id = &quot;footerPanel&quot; > piedipagina </ div > </ body > </ html >
Demo
JavaScript e CSS in Wicket Come abbiamo visto il codice HTML dei pannelli Wicket deve essere una pagina HTML a tutti gli effetti. Se nel file HTML di un pannello vogliamo scrivere (o importare) codice JavaScript o CSS questo va racchiuso nel tag  <wicket:head> < html > < head > < meta   http-equiv = &quot;Content-Type&quot;   content = &quot;text/html; charset=UTF-8&quot; > < title > Insert title here </ title > <wicket:head> <script>...</script> <wicket:head> ... </ head > < body > ... < wicket:panel >  </ wicket:panel > ...
Il framework Wicket Pagine come oggetti
L'ereditariet delle pagine Wicket Ora che abbiamo una pagina di template con il layout del nostro sito, possiamo sfruttare la normale ereditariet degli oggetti per creare le altre pagine. In Wicket una sottoclasse di una pagina eredita dalla classe madre anche l'html  (oltre al codice ovviamente). Questo vuol dire che la pagina figlia avr di default lo stesso identico aspetto della pagina padre. package  helloWorld.layoutTenda; import  org.apache.wicket.markup.html.basic.Label; public   class  ChildPage  extends  JugTemplate { public  ChildPage(){ super (); addOrReplace( new  Label( &quot;contentComponent&quot; ,  &quot;L'ereditariat油 delle pagine Wicket e sia a livello di codice che di  html&quot; )); } }
Pagina figlia del template Per la pagina figlia non 竪 stato necessario creare un HTML . Abbiamo solo personalizzato il contenuto. addOrReplace( new  Label( &quot;contentComponent&quot; ,  &quot;L'ereditariat油 delle pagine Wicket e sia a livello di codice che di html&quot; ));
Il framework Wicket I link e lo stato delle pagine
I Wicket link In Wicket i link sono molto pi湛 complessi del loro corrispondente HTML e non hanno come scopo esclusivo quello di permettere ad un utente di cambiare pagina. Come gli altri componenti Wicket i link sono associabili ad un tag della pagina HTML tramite l'attributo  wicket:id . Si noti che un link  non deve per forza essere associato ad un tag anchor   <a>  ma pu嘆 essere associato a qualsiasi tag che supporti l'evento JavaScript  onClick  (quasi tutti quindi) . Quando si aggiunge un componente Link ad una pagina occorre sovrascrivere il metodo onClick() per specificare cosa deve essere fatto quando l'utente preme il link: add( new   Link( &quot;link&quot; ) { @Override public   void  onClick() { } });
I Wicket link 2 Se si vuole cambiare pagina facendo click su un Link Wicket occorre esplicitarlo nel metodo onClick() usando la funzione setResponsePage(): Se un link non mi fa cambiare pagina Wicket restituisce nuovamente la pagina corrente,  senza per嘆 ricrearne un'istanza nuova, conservando quindi lo stato della mia pagina fino a quando non la abbandono. ( Vi ricordate all'inizio  il problema della conservazione dello stato in HTTP?) add( new   Link( &quot;link&quot; ) { @Override public   void  onClick() { setResponsePage(JugTemplate.class); } });
Il metodo onBeforeRender Una pagina Wicket prima di essere trasmessa al browser effettua il  pre-rendering  tramite l'evento  before render  che viene gestito nel metodo onBeforeRender della classe WebPage. Sovrascrivendo questo metodo possiamo ulteriormente modificare l'aspetto e i componenti della pagina. Abbiamo detto che se un Link Wicket non causa il cambiamento di pagina viene restituita la pagina che lo contiene,  senza  creare una nuova istanza.  Dopo il click il costruttore della pagina non verr invocato mai il metodo onBeforeRender si!
Pagina di esempio sui Link Nella pagina di esempio abbiamo due timestamp, uno aggiunto nel costruttore della pagina e l'altro nel metodo  onBeforeRender() . Sono presenti anche due link che non fanno cambiare pagina. Cliccando sui link si aggiorna solo il timestamp costruito su  onBeforeRender().
Codice della pagina di esempio public   class  HomePage  extends  WebPage { public   HomePage (){ super (); add( new  Label( &quot;label&quot; ,  &quot;Hello World&quot; )); add( new  Label( &quot;timeStamp&quot; ,  &quot;&quot;  +  new  Date())); add( new   Link( &quot;link&quot; ) { @Override public   void  onClick() { } }); add( new  Link( &quot;spanLink&quot; ){ @Override public   void  onClick() { } } ); .... @Override protected   void   onBeforeRender () { super .onBeforeRender(); addOrReplace( new  Label( &quot;timeStampFresh&quot; ,  &quot;&quot;  +  new  Date())); } }
Il framework Wicket Il model dei componenti Wicket
Il ruolo del model in wicket 1 Tutti  i componenti Wicket (input form, radio button, select ecc...) memorizzano il valore ad essi associato in un'istanza dell'interfaccia Imodel e dispongono di un metodo getModel() per accedervi dall'esterno. Anche se ogni componente Wicket pu嘆 avere un model il suo significato e la sua utilit diventano chiari quando si usano i componenti di una form (campi testo, select, radio button...) che memorizzano nel model il valore inserito in input dall'utente. Attraverso il model Wicket offre uno strumento universale per leggere i valori dei suoi componenti, come il contenuto di un campo testuale o l'opzione scelta in una select. public interface IModel { public Object getObject(); public void setObject(final Object object); }
Il ruolo del model in wicket 2 Anche le Label hanno un model associato, ed 竪 il secondo parametro stringa del costruttore che viene visualizzato nella label: add( new  Label( &quot;label&quot; ,  &quot;Hello World&quot; )); ... Nel caso della Label il modello 竪 creato implicitamente dal costruttore e contiene la stringa passata come secondo argomento.  Le classi model possono contenere una generica istanza di object ma di solito si ricorre al meccanismo dei  generics  per esplicitare il tipo di istanza in essi contenuta new  Model<String>( &quot;label&quot; );
new  Model<Persona>( new   Persona( Mario ,  Rossi ));
I Form di Wicket Wicket fornisce una sua classe Form per mappare i form HTML in oggetti Java ed associare a loro uno stato. Il mapping tra classe e tag avviene sempre attraverso l'attributo  wicket:id : < form   wicket:id = &quot;form&quot; > ... Cos狸 come il form HTML anche il corrispondente Wicket si caratterizza in base ai controlli di input che contiene (text field, select, radio button, ecc...) e i pulsanti di submit (di solito uno solo) che avviano la trasmissione dei dati al server. Quindi anche il Form Wicket cos狸 come le pagine ed i pannelli  竪 un componente  container, ossia pu嘆 contenere altri componenti al suo interno che devono per嘆 essere sottoclassi di FormComponent.
Il componente TextField Ora vediamo un esempio di model pi湛 chiaro, realizzando una pagina di login con due campi testuali username e password. I campi testuali di una form vengono mappati in Wicket con la classe  TextField  e di solito 竪 utile associare un model String che memorizza il valore inserito dall'utente. Purtroppo i TextField di Wicket non hanno un costruttore che crea in automatico il model secondo il tipo desiderato e dobbiamo farlo a mano :-(: Esempio di mapping di un campo testo di una form:
Classe Java
new  TextField<String>( username , new   Model<String>( Inserisci  il tuo username )); Codice HTML Username:  < input   type = &quot;text&quot;   wicket:id = &quot;username&quot; />
Prototipo maschera di login
Il pannello di login (HTML) < html >  < wicket:panel > < div   style = &quot;margin: auto; width: 40%&quot;   class = &quot;crop_content_contenuti&quot; > < form   id = &quot;ricerca&quot;   method = &quot;get&quot;   wicket:id = &quot;form&quot; > < fieldset   id = &quot;ricerca1&quot;   class = &quot;center&quot; > < legend   wicket:id = &quot;message&quot; > Ricerca </ legend > < p   wicket:id = &quot;loginStatus&quot;   style = &quot;font-weight: bold;color: red;text-align: left&quot; ></ p > < span > Username:  </ span > < input   wicket:id = &quot;username&quot;   type = &quot;text&quot;   id = &quot;username&quot;   />< br /> < span   > Password:  </ span > < input   wicket:id = &quot;password&quot;   type = &quot;password&quot;   id = &quot;password&quot;   /> < p > < input   type = &quot;submit&quot;   name = &quot;login&quot;   value = &quot;login&quot; /> </ p > </ fieldset > </ form > </ div > </ wicket:panel >  </ html > Nella pannello di login oltre ai campi username/password abbiamo inserito anche un titolo attraverso il tag <legend> e abbiamo inserti un paragrafo che contiene eventuali messaggi di errore se il login non va a buon fine.
Il pannello e la form di login (Java) 1 public   class  LoginPanel  extends  Panel { public  LoginPanel(String id) { super (id); init(); } private   void  init(){ Form loginForm =  new  LoginForm( &quot;form&quot; ); add(loginForm); } } Il pannello di login serve esclusivamente da wrapper per l'oggetto form vero e proprio che contiene i campi username e epassword e che gestisce il login.
Il pannello e la form di login (Java) 2 public   class  LoginForm  extends  Form { private  TextField  usernameField  =  null ; private  PasswordTextField  passwordField  =  null ; private  Label  loginStatus  =  null ; public  LoginForm( final  String componentName) { super (componentName); usernameField  =  new  TextField( &quot;username&quot; ,  new  Model<String>( &quot;&quot; )); passwordField  =  new  PasswordTextField( &quot;password&quot; ,  new   Model<String>( &quot;&quot; )); loginStatus  =  new  Label( &quot;loginStatus&quot; ); add( usernameField ); add( passwordField ); add( new  Label( &quot;message&quot; ,  &quot;Login&quot; )); add( loginStatus ); } public   final   void  onSubmit() { String username =  usernameField .getValue(); String password =  passwordField .getValue(); if ((username.equals( &quot;Mario&quot; ) && password.equals( &quot;Rossi&quot; ))) loginStatus .setDefaultModel( new  Model<String>( &quot;Complimenti!&quot; )); else loginStatus .setDefaultModel( new  Model<String>( &quot;Username o    password errate!&quot; )); } Wicket dispone di un componente apposito per i campi password. L'evento onSubmit della form scatta prima di inviare i parametri della form al server.
Il pannello di login (Java) public   class  LoginPanel  extends  Panel { public  LoginPanel(String id) { super (id); init(); } private   void  init(){ Form loginForm =  new  LoginForm( &quot;form&quot; ); add(loginForm); } public   final   class  LoginForm  extends  Form { private  TextField  usernameField  =  null ; private  PasswordTextField  passwordField  =  null ; private  Label  loginStatus  =  null ; public  LoginForm( final  String componentName) { super (componentName); usernameField  =  new  TextField( &quot;username&quot; ,  new  Model<String>( &quot;&quot; )); passwordField  =  new  PasswordTextField( &quot;password&quot; ,  new  Model<String>( &quot;&quot; )); loginStatus  =  new  Label( &quot;loginStatus&quot; ); add( usernameField ); add( passwordField ); add( new  Label( &quot;message&quot; ,  &quot;Login&quot; )); add( loginStatus ); } public   final   void  onSubmit() { String username =  usernameField .getValue(); String password =  passwordField .getValue(); if ((username.equals( &quot;Mario&quot; ) && password.equals( &quot;Rossi&quot; ))) loginStatus .setDefaultModel( new  Model<String>( &quot;Complimenti!&quot; )); else loginStatus .setDefaultModel( new  Model<String>( &quot;Username o password errate!&quot; )); ... Wicket dispone di un componente apposito per i campi password. L'evento onSubmit della form scatta prima di inviare i parametri della form al server.
La pagina di login Visto che ci siamo usiamo il layout di Jug4Tenda..... package  helloWorld.layoutTenda; import  helloWorld.LoginPanel; import  org.apache.wicket.markup.html.basic.Label; public   class  LoginPage  extends  JugTemplate { public  LoginPage(){ super (); addOrReplace( new  LoginPanel( &quot;contentComponent&quot; )); } }
Demo
Il framework Wicket Gestione avanzata dello stato
I repeat viewer
I bean come model Wicket Abbiamo visto cosa 竪 il model in Wicket e lo abbiamo applicato nel modo pi湛 semplice possibile agli oggetti TextField Tuttavia la vera utilit del model si comprende usando funzioni pi湛 raffinate che permettono di associare a form e controlli delle semplici istanze di Java Bena da usare come model.  Ci嘆 permette di ragionare in maniera completamente object oriented e di usare il model di wicket in maniera molto pi湛 naturale. Esempio:  Vogliamo realizzare un pannello e con una form con dei semplici dati anagrafici (nome, cognome, indirizzo, email). Premendo submit la form: crea un'istanza della classe Person (il nostro JavaBean) che contiene i dati anagrafici
la aggiunge alla lista di istanze precedentemente create
visualizza le istanze della lista.
Il JavaBean Person package  helloWorld; import  java.io.Serializable; public   class   Person   implements  Serializable { private  String  name ; private  String  sureName ; private  String  address ; private  String  email ; public  String getAddress() { return   address ; } public   void  setAddress(String address) { this . address  = address; } public  String getEmail() { return   email ; } public   void  setEmail(String email) { this . email  = email; } public  String getName() { return   name ; } public   void  setName(String name) { this . name  = name; } public  String getSureName() { return   sureName ; } public   void  setSureName(String sureName) { this . sureName  = sureName; } }
La form class   CreatePerson   extends   Form { private  Person  person  =  new  Person(); public  Person getPerson() { return   person ; } public  CreatePerson(String id) { super (id); setDefaultModel( new  CompoundPropertyModel<Person>( this )); add( new  TextField<String>( &quot;person.name&quot; )); add( new  TextField<String>( &quot;person.sureName&quot; )); add( new  TextField<String>( &quot;person.address&quot; )); add( new  TextField<String>( &quot;person.email&quot; )); } @Override protected   void  onSubmit() { super .onSubmit(); personsArray .add( person ); person  =  new  Person(); } }
La form class   CreatePerson   extends   Form { private  Person  person  =  new  Person(); public  Person getPerson() { return   person ; } public  CreatePerson(String id) { super (id); setDefaultModel( new  CompoundPropertyModel<Person>( this )); add( new  TextField<String>( &quot;person.name&quot; )); add( new  TextField<String>( &quot;person.sureName&quot; )); add( new  TextField<String>( &quot;person.address&quot; )); add( new  TextField<String>( &quot;person.email&quot; )); } @Override protected   void  onSubmit() { super .onSubmit(); personsArray .add( person ); person  =  new  Person(); } } Si traduce in  getPerson().getPerson().set/getName , quindi il TextFiled legge/scrive direttamente sui campi dell'istanza di Person Uso la stessa form come modello per i miei dati ed avr嘆 accesso ai sui campi La form sar una inner class del pannello 竪 vedr la sua variabile  personsArray

More Related Content

Similar to Presentazione wicket (20)

Lab Web Prof.Di Blasi 2008
Lab Web Prof.Di Blasi 2008Lab Web Prof.Di Blasi 2008
Lab Web Prof.Di Blasi 2008
ninam87
Rich Ajax Web Interfaces in Jquery
Rich Ajax Web Interfaces in JqueryRich Ajax Web Interfaces in Jquery
Rich Ajax Web Interfaces in Jquery
Alberto Buschettu
react-it.pdf
react-it.pdfreact-it.pdf
react-it.pdf
ssuser65180a
Web writing 2
Web writing 2Web writing 2
Web writing 2
icferrucci
Presentazione Corso - Parte 1
Presentazione Corso - Parte 1Presentazione Corso - Parte 1
Presentazione Corso - Parte 1
Giorgio Carpoca
Introduzione ad angular 7/8
Introduzione ad angular 7/8Introduzione ad angular 7/8
Introduzione ad angular 7/8
Valerio Radice
Training Signal Webtrends
Training Signal WebtrendsTraining Signal Webtrends
Training Signal Webtrends
Stefano Iaboni
Many Designs Elements
Many Designs ElementsMany Designs Elements
Many Designs Elements
Giampiero Granatella
JSP Tag Library
JSP Tag LibraryJSP Tag Library
JSP Tag Library
jgiudici
JSP Tag Library
JSP Tag LibraryJSP Tag Library
JSP Tag Library
jgiudici
JSP Tag Library
JSP Tag LibraryJSP Tag Library
JSP Tag Library
jgiudici
Asp.Net MVC 3 - Il Model View Controller secondo Microsoft
Asp.Net MVC 3 - Il Model View Controller secondo MicrosoftAsp.Net MVC 3 - Il Model View Controller secondo Microsoft
Asp.Net MVC 3 - Il Model View Controller secondo Microsoft
Stefano Benedetti
Dal Click Al Web Server
Dal Click Al Web ServerDal Click Al Web Server
Dal Click Al Web Server
Marco Muzzarelli
Ajax
AjaxAjax
Ajax
davide ficano
I Linguaggi Del Web (1属 Giornata)
I Linguaggi Del Web (1属 Giornata)I Linguaggi Del Web (1属 Giornata)
I Linguaggi Del Web (1属 Giornata)
Diego La Monica
Yagwto
YagwtoYagwto
Yagwto
maraexception
HTML e CSS
HTML e CSSHTML e CSS
HTML e CSS
Manuel Scapolan
Asp.net 4 Community Tour VS2010
Asp.net 4 Community Tour VS2010Asp.net 4 Community Tour VS2010
Asp.net 4 Community Tour VS2010
Fabrizio Bernabei
Lab Web Prof.Di Blasi 2008
Lab Web Prof.Di Blasi 2008Lab Web Prof.Di Blasi 2008
Lab Web Prof.Di Blasi 2008
ninam87
Rich Ajax Web Interfaces in Jquery
Rich Ajax Web Interfaces in JqueryRich Ajax Web Interfaces in Jquery
Rich Ajax Web Interfaces in Jquery
Alberto Buschettu
Web writing 2
Web writing 2Web writing 2
Web writing 2
icferrucci
Presentazione Corso - Parte 1
Presentazione Corso - Parte 1Presentazione Corso - Parte 1
Presentazione Corso - Parte 1
Giorgio Carpoca
Introduzione ad angular 7/8
Introduzione ad angular 7/8Introduzione ad angular 7/8
Introduzione ad angular 7/8
Valerio Radice
Training Signal Webtrends
Training Signal WebtrendsTraining Signal Webtrends
Training Signal Webtrends
Stefano Iaboni
JSP Tag Library
JSP Tag LibraryJSP Tag Library
JSP Tag Library
jgiudici
JSP Tag Library
JSP Tag LibraryJSP Tag Library
JSP Tag Library
jgiudici
JSP Tag Library
JSP Tag LibraryJSP Tag Library
JSP Tag Library
jgiudici
Asp.Net MVC 3 - Il Model View Controller secondo Microsoft
Asp.Net MVC 3 - Il Model View Controller secondo MicrosoftAsp.Net MVC 3 - Il Model View Controller secondo Microsoft
Asp.Net MVC 3 - Il Model View Controller secondo Microsoft
Stefano Benedetti
Dal Click Al Web Server
Dal Click Al Web ServerDal Click Al Web Server
Dal Click Al Web Server
Marco Muzzarelli
I Linguaggi Del Web (1属 Giornata)
I Linguaggi Del Web (1属 Giornata)I Linguaggi Del Web (1属 Giornata)
I Linguaggi Del Web (1属 Giornata)
Diego La Monica
Asp.net 4 Community Tour VS2010
Asp.net 4 Community Tour VS2010Asp.net 4 Community Tour VS2010
Asp.net 4 Community Tour VS2010
Fabrizio Bernabei

Presentazione wicket

  • 1. Il framework Wicket Andrea Del Bene Jug Marche [email_address]
  • 2. Quali sono i guai della programmazione web? Le tecnologie su cui si basa il web si basano su paradigmi molto diversi da quelli dei linguaggi di programmazione moderni (OOP in primis). Quando scegliamo le pagine web come GUI dobbiamo affrontare due grossi limiti di questa tecnologia: Le pagine (le viste del programma) sono dei semplici file di testo da spedire al browser e non possono essere rappresentate ed usate con gli strumenti dell'OOP
  • 3. L'HTTP 竪 stateless e dobbiamo fare i salti mortali per associare uno stato alla navigazione di un utente sul nostro sito (di solito si ricorre all'oggetto Session)
  • 4. Wicket: pagine come oggetto Wicket 竪 un framework a componenti per lo sviluppo di soluzioni web Java che propone una soluzione ad entrambi i problemi visti A differenza di altre soluzioni (JSP, Struts, Spring MVC, ecc...) le pagine web sono trattate come vere e proprie istanze di oggetto (classe WebPage ). Non dobbiamo pi湛 usare direttamente Request e Response nel nostro codice e l'HTML 竪 usato solo come template di visualizzazione, non contiene n竪 taglib n竪 codice java. Come vedremo trattare le pagine come oggetti offre una soluzione trasparente anche al problema della conservazione dello stato... Per fare ci嘆 Wicket offre una gerarchia di classi molto simile a quella proposta da Swing per realizzare le GUI di applicazioni desktop
  • 5. Wicket VS Swing In Wicket ogni entit 竪 un componente e la pagina (la classe WebPage) contiene a sua volta istanze di componenti. WebPage ha una funzione analoga alla classe JWindow (o JFrame) in Swing.
  • 6. Dov'竪 finito l'HTML? Se la pagina per lo sviluppatore 竪 una classe Java come ottengo l'HTML finale da inviare al Browser? In Wicket la classe che rappresenta una pagina ha associata una pagina HTML standard che funziona da template e che per default deve trovarsi nella stessa cartella della classe ed avere lo stesso nome . La classe Wicket pu嘆 mappare i suoi componenti interni con i tag presenti nella pagina HTML. Wicket offre un set di componenti con cui mappare i vari elementi di una pagina HTML ( paragrafi <p>, form, div, span, controlli di input, ecc...)
  • 7. Il file web.xml E' il momento di vedere un primo esempio di utilizzo di Wicket. L'applicazione 竪 una classica web application Java. Il file web.xml deve dichiarare un elemento <filter> che istanzi una sottoclasse di org.apache.wicket.protocol.http.WebApplication (nel nostro caso la classe helloWorld.WicketApplication ). <? xml version = &quot;1.0&quot; encoding = &quot;UTF-8&quot; ?> <! DOCTYPE web-app PUBLIC &quot;-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN&quot; &quot;http://java.sun.com/dtd/web-app_2_3.dtd&quot; > < web-app > < display-name > Wicket HelloWorld </ display-name > < filter > < filter-name > WizardApplication </ filter-name > < filter-class > org.apache.wicket.protocol.http.WicketFilter </ filter-class > < init-param > < param-name > applicationClassName </ param-name > < param-value > helloWorld.WicketApplication </ param-value > </ init-param > </ filter > < filter-mapping > < filter-name > WizardApplication </ filter-name > < url-pattern > /* </ url-pattern > </ filter-mapping > </ web-app >
  • 8. La classe WicketApplication package helloWorld; import org.apache.wicket.Page; import org.apache.wicket.protocol.http.WebApplication; public class WicketApplication extends WebApplication { @Override public Class<? extends Page> getHomePage() { return HomePage. class ; } } La classe WicketApplication oltre ad essere il cardine dell'applicazione Wicket, pu嘆 sovrascrivere numerosi metodi della classe madre per customizzare il comportamento della nostra applicazione. Sovrascrivendo la funzione getHomePage si pu嘆 specificare la pagina home page della nostra applicazione (HomePage nel nostro caso).
  • 9. Pagina HelloWorld La mappatura tra elementi HTML ed oggetti Java avviene aggiungendo al tag l'attributo wicket:id= < html > < head > < meta http-equiv = &quot;Content-Type&quot; content = &quot;text/html; charset=UTF-8&quot; > < title > Insert title here </ title > </ head > < body > < h1 wicket:id = &quot;label&quot; ></ h1 > </ body > </ html > Nella classe della pagina Wicket bisogna aggiungere un componente con id uguale al wicket:id dell'elemento che si vuole mappare. package helloWorld; import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.markup.html.basic.Label; public class HomePage extends WebPage { public HomePage(){ super (); add( new Label( &quot;label&quot; , &quot;Hello World&quot; )); } } HelloWorld.html HelloWorld.java
  • 10. WicketHelloWorld Nel tag <h1> 竪 stato inserito il testo fornito come secondo parametro nel costruttore del componente Label. ... < body > < h1 wicket:id = &quot;label&quot; ></ h1 > </ body > ... ... public HomePage(){ super (); add( new Label( &quot;label&quot; , &quot;Hello World&quot; )); } ...
  • 11. Wicket come template per layout L'esempio appena visto usa in maniera molto primitiva la capacit di Wicket di manipolare il contenuto di una pagina HTML usando codice Java. Questa tecnica pu嘆 essere usata per creare il layout grafico delle nostre pagine usando un numero arbitrario di wicket:id nella nostra pagina ed inniettando il codice HTML dei vari elementi che la compongono (ad esempio: l'header, il men湛 di navigazione, il footer, il contenuto, ecc...) Per fare ci嘆 useremo l'oggetto Panel di Wicket che permette di associare il contenuto di una pagina HTML ad un componente custom di Wicket e poterlo aggiungere in una pagina del framework.
  • 12. Il framework Wicket Il layout con Wicket
  • 13. Layout di una pagina web Ora vogliamo espandere quanto visto nell'esempio precedente per creare un classico layout per le pagine del nostro sito: un header, un men湛 di sinistra, il contenuto centrale ed un footer conclusivo. Header Men湛 Contenuto Footer
  • 14. L'approccio classico Di solito per conferire alle pagine un layout stabilito ci si affida a tecnologie di templating server side che caricano i vari pezzi della pagina prima di spedirla al browser. <%@include file=&quot;../common/Jug4TendaHeader.jsp&quot;%> <%@include file= &quot;gestioneOspiteMenu.htm &quot;%> <div id=&quot;Content&quot;> <%@include file=&quot;../common/Jug4TendaFooter.jsp&quot;%>
  • 15. Layout in Wicket Con Wicket possiamo creare una pagina di template principale (chiamiamola Jug4TendaTemplate) suddivisa nei componenti desiderati, ognuno rappresentato da un <div> e con il proprio wicket:id <div wicket:id=headerPanel></div> <div wicket:id=menuPanel> </div> <div wicket:id=contentPanel></div> <div wicket:id=footerPanel></div>
  • 16. I pannelli di Wicket I pannelli sono lo strumento con cui possiamo creare componenti personalizzati. Di fatto sono quasi come le pagine Wicket vere e proprio in quanto anche i pannelli: Sono associati a pagine HTML (pagine HTML complete !)
  • 17. Possono a loro volta contenere altri componenti A differenza delle pagine per嘆 i pannelli non possono essere rendereizzati stand alone , ma devono essere inseriti in una pagina web I pannelli sono gli strumenti ideali per suddividere la pagina nei sui componenti grafici e per poterli riutilizzare in pi湛 pagine.
  • 18. Il pannello header < html > < head > < meta http-equiv = &quot;Content-Type&quot; content = &quot;text/html; charset=UTF-8&quot; > < title > Insert title here </ title > </ head > < body > <wicket:panel> < table width = &quot;100%&quot; style = &quot;border: 0px none;&quot; > < tbody >< tr > < td >< img alt = &quot;Jug4Tenda&quot; src = /slideshow/presentazione-wicket/6504675/&quot;wicketLayout_files/logo_jug4tenda.gif&quot; ></ td > < td >< h1 > Gestione Anagrafica Accoglienze </ h1 ></ td > < td >< img alt = &quot;Associazione di volontariato La Tenda d'Abramo&quot; src = &quot;wicketLayout_files/logo_latendadabramo.gif&quot; ></ td > </ tr > </ tbody > </ table > </wicket:panel> </ body > </ html > HeaderPanel.html La pagina HTML di un pannello deve avere il tag <wicket:panel> all'interno del quale si trova l'HTML del pannello stesso.
  • 19. La classe del pannello header package helloWorld.layoutTenda; import org.apache.wicket.markup.html.panel.Panel; public class HeaderPanel extends Panel { public HeaderPanel(String id) { super (id); } } HeaderPanel.java La classe di un pannello Wicket deve avere almeno un costruttore che richiama il costruttore padre passandogli il wicket id come parametro stringa. Anche i pannelli cos狸 come le pagine devono avere la classe e il file HTML nella stessa cartella e devono avere lo stesso nome.
  • 20. Il pannello footer < wicket:panel > < span class = &quot;piccolo&quot; > Powered by </ span > < a target = &quot;_blank&quot; title = &quot;vai al sito dello JUG Ancona,.. href = &quot;http://www.jugancona.it/&quot; > < img title = &quot;vai al sito dello JUG Ancona, ...&quot; alt = &quot;JUG Ancona, Java User Group di Ancona&quot; src = /slideshow/presentazione-wicket/6504675/&quot;wicketLayout_files/logo_jugancona.gif&quot; ></ a > < img title = &quot;JUG, Java User Group&quot; alt = &quot;JUG, Java User Group&quot; src = &quot;wicketLayout_files/logo_jug.gif&quot; > < a title = &quot;vai al sito del framework Spring &quot; href = &quot;http://www.springframework.org/&quot; > < img title = &quot;vai al sito del framework Spring&quot; alt = &quot;Spring&quot; src = &quot;wicketLayout_files/logo_spring.gif&quot; ></ a > < a title = &quot;vai al sito di Mozilla Firefox...&quot; href = &quot;http://www.mozilla.com/&quot; > < img title = &quot;vai al sito di Mozilla Firefox...&quot; alt = &quot;Firefox&quot; src = &quot;wicketLayout_files/logo_firefox.gif&quot; ></ a > </ wicket:panel > FooterPanel.html package helloWorld.layoutTenda; import org.apache.wicket.markup.html.panel.Panel; public class FooterPanel extends Panel { public FooterPanel(String id) { super (id); } } HeaderPanel.java
  • 21. Il pannello menu <div class=&quot;menuTitle&quot;>Menu principale</div> <ul class=&quot;menuItems&quot;> <li> <img src=/slideshow/presentazione-wicket/6504675/&quot;wicketLayout_files/home.gif&quot;> <a class=&quot;Offmouse&quot; href=&quot;http://localhost:8080/jug4tenda/index.jsp&quot; id=&quot;newOspite&quot; onmouseout=&quot;this.className='Offmouse'&quot; onmouseover=&quot;this.className='Onmouse'&quot;>Home</a></li> </ul> MenuPanel.html package helloWorld.layoutTenda; import org.apache.wicket.markup.html.panel.Panel; public class Menu Panel extends Panel { public Menu Panel (String id) { super (id); } } MenuPanel.java
  • 22. La pagina template Jug4Wicket package helloWorld.layoutTenda; import org.apache.wicket.markup.html.WebPage; public class JugTemplate extends WebPage { public JugTemplate(){ add( new HeaderPanel( &quot;headerPanel&quot; ) ); add( new MenuPanel( &quot;menuPanel&quot; ) ); add( new FooterPanel( &quot;footerPanel&quot; ) ); add( new Label( &quot;contentComponent&quot;, &quot;content&quot; ) ); } } < html > < head > < meta http-equiv = &quot;Content-Type&quot; content = &quot;text/html; charset=UTF-8&quot; > < title > Jug4Tenda - Home page </ title > ... </ head > < body > < div id = &quot;intestazione&quot; wicket:id = &quot;headerPanel&quot; > intestazione </ div > < div id = &quot;pagina&quot; > < div id = &quot;Menu&quot; wicket:id = &quot;menuPanel&quot; > Menu </ div > < div id = &quot;Content&quot; wicket:id = &quot;content&quot; > Content </ div > </ div > < div id = &quot;piedipagina&quot; wicket:id = &quot;footerPanel&quot; > piedipagina </ div > </ body > </ html >
  • 23. Demo
  • 24. JavaScript e CSS in Wicket Come abbiamo visto il codice HTML dei pannelli Wicket deve essere una pagina HTML a tutti gli effetti. Se nel file HTML di un pannello vogliamo scrivere (o importare) codice JavaScript o CSS questo va racchiuso nel tag <wicket:head> < html > < head > < meta http-equiv = &quot;Content-Type&quot; content = &quot;text/html; charset=UTF-8&quot; > < title > Insert title here </ title > <wicket:head> <script>...</script> <wicket:head> ... </ head > < body > ... < wicket:panel > </ wicket:panel > ...
  • 25. Il framework Wicket Pagine come oggetti
  • 26. L'ereditariet delle pagine Wicket Ora che abbiamo una pagina di template con il layout del nostro sito, possiamo sfruttare la normale ereditariet degli oggetti per creare le altre pagine. In Wicket una sottoclasse di una pagina eredita dalla classe madre anche l'html (oltre al codice ovviamente). Questo vuol dire che la pagina figlia avr di default lo stesso identico aspetto della pagina padre. package helloWorld.layoutTenda; import org.apache.wicket.markup.html.basic.Label; public class ChildPage extends JugTemplate { public ChildPage(){ super (); addOrReplace( new Label( &quot;contentComponent&quot; , &quot;L'ereditariat油 delle pagine Wicket e sia a livello di codice che di html&quot; )); } }
  • 27. Pagina figlia del template Per la pagina figlia non 竪 stato necessario creare un HTML . Abbiamo solo personalizzato il contenuto. addOrReplace( new Label( &quot;contentComponent&quot; , &quot;L'ereditariat油 delle pagine Wicket e sia a livello di codice che di html&quot; ));
  • 28. Il framework Wicket I link e lo stato delle pagine
  • 29. I Wicket link In Wicket i link sono molto pi湛 complessi del loro corrispondente HTML e non hanno come scopo esclusivo quello di permettere ad un utente di cambiare pagina. Come gli altri componenti Wicket i link sono associabili ad un tag della pagina HTML tramite l'attributo wicket:id . Si noti che un link non deve per forza essere associato ad un tag anchor <a> ma pu嘆 essere associato a qualsiasi tag che supporti l'evento JavaScript onClick (quasi tutti quindi) . Quando si aggiunge un componente Link ad una pagina occorre sovrascrivere il metodo onClick() per specificare cosa deve essere fatto quando l'utente preme il link: add( new Link( &quot;link&quot; ) { @Override public void onClick() { } });
  • 30. I Wicket link 2 Se si vuole cambiare pagina facendo click su un Link Wicket occorre esplicitarlo nel metodo onClick() usando la funzione setResponsePage(): Se un link non mi fa cambiare pagina Wicket restituisce nuovamente la pagina corrente, senza per嘆 ricrearne un'istanza nuova, conservando quindi lo stato della mia pagina fino a quando non la abbandono. ( Vi ricordate all'inizio il problema della conservazione dello stato in HTTP?) add( new Link( &quot;link&quot; ) { @Override public void onClick() { setResponsePage(JugTemplate.class); } });
  • 31. Il metodo onBeforeRender Una pagina Wicket prima di essere trasmessa al browser effettua il pre-rendering tramite l'evento before render che viene gestito nel metodo onBeforeRender della classe WebPage. Sovrascrivendo questo metodo possiamo ulteriormente modificare l'aspetto e i componenti della pagina. Abbiamo detto che se un Link Wicket non causa il cambiamento di pagina viene restituita la pagina che lo contiene, senza creare una nuova istanza. Dopo il click il costruttore della pagina non verr invocato mai il metodo onBeforeRender si!
  • 32. Pagina di esempio sui Link Nella pagina di esempio abbiamo due timestamp, uno aggiunto nel costruttore della pagina e l'altro nel metodo onBeforeRender() . Sono presenti anche due link che non fanno cambiare pagina. Cliccando sui link si aggiorna solo il timestamp costruito su onBeforeRender().
  • 33. Codice della pagina di esempio public class HomePage extends WebPage { public HomePage (){ super (); add( new Label( &quot;label&quot; , &quot;Hello World&quot; )); add( new Label( &quot;timeStamp&quot; , &quot;&quot; + new Date())); add( new Link( &quot;link&quot; ) { @Override public void onClick() { } }); add( new Link( &quot;spanLink&quot; ){ @Override public void onClick() { } } ); .... @Override protected void onBeforeRender () { super .onBeforeRender(); addOrReplace( new Label( &quot;timeStampFresh&quot; , &quot;&quot; + new Date())); } }
  • 34. Il framework Wicket Il model dei componenti Wicket
  • 35. Il ruolo del model in wicket 1 Tutti i componenti Wicket (input form, radio button, select ecc...) memorizzano il valore ad essi associato in un'istanza dell'interfaccia Imodel e dispongono di un metodo getModel() per accedervi dall'esterno. Anche se ogni componente Wicket pu嘆 avere un model il suo significato e la sua utilit diventano chiari quando si usano i componenti di una form (campi testo, select, radio button...) che memorizzano nel model il valore inserito in input dall'utente. Attraverso il model Wicket offre uno strumento universale per leggere i valori dei suoi componenti, come il contenuto di un campo testuale o l'opzione scelta in una select. public interface IModel { public Object getObject(); public void setObject(final Object object); }
  • 36. Il ruolo del model in wicket 2 Anche le Label hanno un model associato, ed 竪 il secondo parametro stringa del costruttore che viene visualizzato nella label: add( new Label( &quot;label&quot; , &quot;Hello World&quot; )); ... Nel caso della Label il modello 竪 creato implicitamente dal costruttore e contiene la stringa passata come secondo argomento. Le classi model possono contenere una generica istanza di object ma di solito si ricorre al meccanismo dei generics per esplicitare il tipo di istanza in essi contenuta new Model<String>( &quot;label&quot; );
  • 37. new Model<Persona>( new Persona( Mario , Rossi ));
  • 38. I Form di Wicket Wicket fornisce una sua classe Form per mappare i form HTML in oggetti Java ed associare a loro uno stato. Il mapping tra classe e tag avviene sempre attraverso l'attributo wicket:id : < form wicket:id = &quot;form&quot; > ... Cos狸 come il form HTML anche il corrispondente Wicket si caratterizza in base ai controlli di input che contiene (text field, select, radio button, ecc...) e i pulsanti di submit (di solito uno solo) che avviano la trasmissione dei dati al server. Quindi anche il Form Wicket cos狸 come le pagine ed i pannelli 竪 un componente container, ossia pu嘆 contenere altri componenti al suo interno che devono per嘆 essere sottoclassi di FormComponent.
  • 39. Il componente TextField Ora vediamo un esempio di model pi湛 chiaro, realizzando una pagina di login con due campi testuali username e password. I campi testuali di una form vengono mappati in Wicket con la classe TextField e di solito 竪 utile associare un model String che memorizza il valore inserito dall'utente. Purtroppo i TextField di Wicket non hanno un costruttore che crea in automatico il model secondo il tipo desiderato e dobbiamo farlo a mano :-(: Esempio di mapping di un campo testo di una form:
  • 41. new TextField<String>( username , new Model<String>( Inserisci il tuo username )); Codice HTML Username: < input type = &quot;text&quot; wicket:id = &quot;username&quot; />
  • 43. Il pannello di login (HTML) < html > < wicket:panel > < div style = &quot;margin: auto; width: 40%&quot; class = &quot;crop_content_contenuti&quot; > < form id = &quot;ricerca&quot; method = &quot;get&quot; wicket:id = &quot;form&quot; > < fieldset id = &quot;ricerca1&quot; class = &quot;center&quot; > < legend wicket:id = &quot;message&quot; > Ricerca </ legend > < p wicket:id = &quot;loginStatus&quot; style = &quot;font-weight: bold;color: red;text-align: left&quot; ></ p > < span > Username: </ span > < input wicket:id = &quot;username&quot; type = &quot;text&quot; id = &quot;username&quot; />< br /> < span > Password: </ span > < input wicket:id = &quot;password&quot; type = &quot;password&quot; id = &quot;password&quot; /> < p > < input type = &quot;submit&quot; name = &quot;login&quot; value = &quot;login&quot; /> </ p > </ fieldset > </ form > </ div > </ wicket:panel > </ html > Nella pannello di login oltre ai campi username/password abbiamo inserito anche un titolo attraverso il tag <legend> e abbiamo inserti un paragrafo che contiene eventuali messaggi di errore se il login non va a buon fine.
  • 44. Il pannello e la form di login (Java) 1 public class LoginPanel extends Panel { public LoginPanel(String id) { super (id); init(); } private void init(){ Form loginForm = new LoginForm( &quot;form&quot; ); add(loginForm); } } Il pannello di login serve esclusivamente da wrapper per l'oggetto form vero e proprio che contiene i campi username e epassword e che gestisce il login.
  • 45. Il pannello e la form di login (Java) 2 public class LoginForm extends Form { private TextField usernameField = null ; private PasswordTextField passwordField = null ; private Label loginStatus = null ; public LoginForm( final String componentName) { super (componentName); usernameField = new TextField( &quot;username&quot; , new Model<String>( &quot;&quot; )); passwordField = new PasswordTextField( &quot;password&quot; , new Model<String>( &quot;&quot; )); loginStatus = new Label( &quot;loginStatus&quot; ); add( usernameField ); add( passwordField ); add( new Label( &quot;message&quot; , &quot;Login&quot; )); add( loginStatus ); } public final void onSubmit() { String username = usernameField .getValue(); String password = passwordField .getValue(); if ((username.equals( &quot;Mario&quot; ) && password.equals( &quot;Rossi&quot; ))) loginStatus .setDefaultModel( new Model<String>( &quot;Complimenti!&quot; )); else loginStatus .setDefaultModel( new Model<String>( &quot;Username o password errate!&quot; )); } Wicket dispone di un componente apposito per i campi password. L'evento onSubmit della form scatta prima di inviare i parametri della form al server.
  • 46. Il pannello di login (Java) public class LoginPanel extends Panel { public LoginPanel(String id) { super (id); init(); } private void init(){ Form loginForm = new LoginForm( &quot;form&quot; ); add(loginForm); } public final class LoginForm extends Form { private TextField usernameField = null ; private PasswordTextField passwordField = null ; private Label loginStatus = null ; public LoginForm( final String componentName) { super (componentName); usernameField = new TextField( &quot;username&quot; , new Model<String>( &quot;&quot; )); passwordField = new PasswordTextField( &quot;password&quot; , new Model<String>( &quot;&quot; )); loginStatus = new Label( &quot;loginStatus&quot; ); add( usernameField ); add( passwordField ); add( new Label( &quot;message&quot; , &quot;Login&quot; )); add( loginStatus ); } public final void onSubmit() { String username = usernameField .getValue(); String password = passwordField .getValue(); if ((username.equals( &quot;Mario&quot; ) && password.equals( &quot;Rossi&quot; ))) loginStatus .setDefaultModel( new Model<String>( &quot;Complimenti!&quot; )); else loginStatus .setDefaultModel( new Model<String>( &quot;Username o password errate!&quot; )); ... Wicket dispone di un componente apposito per i campi password. L'evento onSubmit della form scatta prima di inviare i parametri della form al server.
  • 47. La pagina di login Visto che ci siamo usiamo il layout di Jug4Tenda..... package helloWorld.layoutTenda; import helloWorld.LoginPanel; import org.apache.wicket.markup.html.basic.Label; public class LoginPage extends JugTemplate { public LoginPage(){ super (); addOrReplace( new LoginPanel( &quot;contentComponent&quot; )); } }
  • 48. Demo
  • 49. Il framework Wicket Gestione avanzata dello stato
  • 51. I bean come model Wicket Abbiamo visto cosa 竪 il model in Wicket e lo abbiamo applicato nel modo pi湛 semplice possibile agli oggetti TextField Tuttavia la vera utilit del model si comprende usando funzioni pi湛 raffinate che permettono di associare a form e controlli delle semplici istanze di Java Bena da usare come model. Ci嘆 permette di ragionare in maniera completamente object oriented e di usare il model di wicket in maniera molto pi湛 naturale. Esempio: Vogliamo realizzare un pannello e con una form con dei semplici dati anagrafici (nome, cognome, indirizzo, email). Premendo submit la form: crea un'istanza della classe Person (il nostro JavaBean) che contiene i dati anagrafici
  • 52. la aggiunge alla lista di istanze precedentemente create
  • 53. visualizza le istanze della lista.
  • 54. Il JavaBean Person package helloWorld; import java.io.Serializable; public class Person implements Serializable { private String name ; private String sureName ; private String address ; private String email ; public String getAddress() { return address ; } public void setAddress(String address) { this . address = address; } public String getEmail() { return email ; } public void setEmail(String email) { this . email = email; } public String getName() { return name ; } public void setName(String name) { this . name = name; } public String getSureName() { return sureName ; } public void setSureName(String sureName) { this . sureName = sureName; } }
  • 55. La form class CreatePerson extends Form { private Person person = new Person(); public Person getPerson() { return person ; } public CreatePerson(String id) { super (id); setDefaultModel( new CompoundPropertyModel<Person>( this )); add( new TextField<String>( &quot;person.name&quot; )); add( new TextField<String>( &quot;person.sureName&quot; )); add( new TextField<String>( &quot;person.address&quot; )); add( new TextField<String>( &quot;person.email&quot; )); } @Override protected void onSubmit() { super .onSubmit(); personsArray .add( person ); person = new Person(); } }
  • 56. La form class CreatePerson extends Form { private Person person = new Person(); public Person getPerson() { return person ; } public CreatePerson(String id) { super (id); setDefaultModel( new CompoundPropertyModel<Person>( this )); add( new TextField<String>( &quot;person.name&quot; )); add( new TextField<String>( &quot;person.sureName&quot; )); add( new TextField<String>( &quot;person.address&quot; )); add( new TextField<String>( &quot;person.email&quot; )); } @Override protected void onSubmit() { super .onSubmit(); personsArray .add( person ); person = new Person(); } } Si traduce in getPerson().getPerson().set/getName , quindi il TextFiled legge/scrive direttamente sui campi dell'istanza di Person Uso la stessa form come modello per i miei dati ed avr嘆 accesso ai sui campi La form sar una inner class del pannello 竪 vedr la sua variabile personsArray
  • 57. Il pannello < wicket:panel > < div style = &quot;text-align: center;float: left;&quot; > < form wicket:id = &quot;form&quot; id = &quot;form&quot; > ... </ form > </ div > < br style = &quot;clear: both;&quot; ></ br > < span wicket:id = &quot;persons&quot; > < div style = &quot;background-color: rgb(255, 245, 236); border: &quot; > < b > Nome : </ b > < span wicket:id = &quot;personName&quot; ></ span >< br ></ br > < b > Cognome : </ b > < span wicket:id = &quot;personSurename&quot; ></ span >< br ></ br > < b > Indirizzo : </ b > < span wicket:id = &quot;address&quot; ></ span >< br ></ br > < b > Cognome : </ b >< span wicket:id = &quot;email&quot; ></ span > </ div >< br /> </ span > </ wicket:panel > Nel pannello oltre alla form c'竪 un componente con id persons . E'un nuovo tipo di componente Wicket che visualizza collezioni di oggetti ripetendo il codice HTML al suo interno per ogni elemento della collezione.
  • 58. Il pannello public class PersonsManager extends Panel { private List<Person> personsArray = new ArrayList<Person>(); public PersonsManager(String id, List<Person> personsArray) { super (id); add( new CreatePerson( &quot;form&quot; )); PageableListView<Person> persons = new PageableListView<Person>( &quot;persons&quot; , personsArray,30) { @Override protected void populateItem(ListItem<Person> personHtml) { personHtml.add( new Label( &quot;personName&quot; , personHtml.getModel().getObject().getName())); personHtml.add( new Label( &quot;personSurename&quot; , personHtml.getModel().getObject().getSureName())); personHtml.add( new Label( &quot;address&quot; , personHtml.getModel().getObject().getAddress())); personHtml.add( new Label( &quot;email&quot; , personHtml.getModel().getObject().getEmail())); } }; add(persons); this . personsArray = personsArray; } Il codice nell'ellisse 竪 il repeat viewer che visualizza la lista di persone create
  • 59. Demo
  • 60. Conclusioni Pro: Permette di applicare la programmazione OO dal backend alla GUI, quindi...
  • 61. Rende le applicazioni web testabili molto pi湛 facilmente.
  • 62. Gestione dello stato trasparente.
  • 63. Grande variet di componenti pronti all'uso.
  • 64. ... Contro: Cambio di prospettiva radicale!
  • 65. Documentazione utente e tutorial frammentari e scarni.
  • 66. ...
  • 67. Appendice Nascondere i componenti
  • 69. Nascondere i componenti HTML Chi viene da una tecnologia granulare come JSP 竪 abituato ad aggiungere dinamicamente attributi ai tag HTML (come le classi CSS) e a nascondere/visualizzare parti della pagina in maniera condizionata. Si pu嘆 ovviamente fare tutto ci嘆 anche in Wicket via Java... La classe base Component espone il metodo setVisible(boolean) che permette di attivare/disattivare la visibilit di un componente HTML Label sconto = new Label( &quot;sconto&quot; , &quot;Sconto merce&quot; +scontoMerce); if (prezzoMerce < 1000) newLabel.setVisible( false ); Esempio: Vogliamo visualizzare una label con lo sconto sulla merce solo se l'importo 竪 maggiore di 1000 Euro NOTA: quando si imposta la visibilit a false il componente viene totalmente eliminato dall'HTML finale della pagina!
  • 70. Aggiungere attributi ai tag HTML Allo stesso modo possiamo aggiungere attributi ai tag HTML per decorare i nostri componenti della pagina. Esempio: Vogliamo rendere rossa una label con un messaggio importante. Label warning = new Label( &quot;warning&quot; , &quot;Attenzione!&quot; ); warning.add( new SimpleAttributeModifier( &quot;style&quot; , &quot;color:red;&quot; ));
  • 71. Grazie ! Andrea Del Bene JUG Marche - www.jugancona.it