Presentazione wicket

  • 1,146 views
Uploaded on

Presentazione del Jug Ancona relativa al framework web Wicket

Presentazione del Jug Ancona relativa al framework web Wicket

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,146
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
11
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 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 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)
  • 3. 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
  • 4. 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.
  • 5. 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...)
  • 6. 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 = "1.0" encoding = "UTF-8" ?> <! DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > < 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 >
  • 7. 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).
  • 8. Pagina HelloWorld La mappatura tra elementi HTML ed oggetti Java avviene aggiungendo al tag l'attributo wicket:id=”” < html > < head > < meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8" > < title > Insert title here </ title > </ head > < body > < h1 wicket:id = "label" ></ 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( "label" , "Hello World" )); } } HelloWorld.html HelloWorld.java
  • 9. WicketHelloWorld Nel tag <h1> è stato inserito il testo fornito come secondo parametro nel costruttore del componente Label. ... < body > < h1 wicket:id = "label" ></ h1 > </ body > ... ... public HomePage(){ super (); add( new Label( "label" , "Hello World" )); } ...
  • 10. 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.
  • 11. Il framework Wicket Il layout con Wicket
  • 12. 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
  • 13. 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="../common/Jug4TendaHeader.jsp"%> <%@include file= "gestioneOspiteMenu.htm "%> <div id="Content"> <%@include file="../common/Jug4TendaFooter.jsp"%>
  • 14. 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>
  • 15. 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.
  • 16. Il pannello header < html > < head > < meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8" > < title > Insert title here </ title > </ head > < body > <wicket:panel> < table width = "100%" style = "border: 0px none;" > < tbody >< tr > < td >< img alt = "Jug4Tenda" src = "wicketLayout_files/logo_jug4tenda.gif" ></ td > < td >< h1 > Gestione Anagrafica Accoglienze </ h1 ></ td > < td >< img alt = "Associazione di volontariato La Tenda d'Abramo" src = "wicketLayout_files/logo_latendadabramo.gif" ></ 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.
  • 17. 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.
  • 18. Il pannello footer … < wicket:panel > < span class = "piccolo" > Powered by </ span > < a target = "_blank" title = "vai al sito dello JUG Ancona,..” href = "http://www.jugancona.it/" > < img title = "vai al sito dello JUG Ancona, ..." alt = "JUG Ancona, Java User Group di Ancona" src = "wicketLayout_files/logo_jugancona.gif" ></ a > < img title = "JUG, Java User Group" alt = "JUG, Java User Group" src = "wicketLayout_files/logo_jug.gif" > < a title = "vai al sito del framework Spring " href = "http://www.springframework.org/" > < img title = "vai al sito del framework Spring" alt = "Spring" src = "wicketLayout_files/logo_spring.gif" ></ a > < a title = "vai al sito di Mozilla Firefox..." href = "http://www.mozilla.com/" > < img title = "vai al sito di Mozilla Firefox..." alt = "Firefox" src = "wicketLayout_files/logo_firefox.gif" ></ 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
  • 19. Il pannello menu … <div class="menuTitle">Menu principale</div> <ul class="menuItems"> <li> <img src="wicketLayout_files/home.gif"> <a class="Offmouse" href="http://localhost:8080/jug4tenda/index.jsp" id="newOspite" onmouseout="this.className='Offmouse'" onmouseover="this.className='Onmouse'">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
  • 20. La pagina template Jug4Wicket package helloWorld.layoutTenda; import org.apache.wicket.markup.html.WebPage; public class JugTemplate extends WebPage { public JugTemplate(){ add( new HeaderPanel( "headerPanel" ) ); add( new MenuPanel( "menuPanel" ) ); add( new FooterPanel( "footerPanel" ) ); add( new Label( "contentComponent", "content" ) ); } } < html > < head > < meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8" > < title > Jug4Tenda - Home page </ title > ... </ head > < body > < div id = "intestazione" wicket:id = "headerPanel" > intestazione </ div > < div id = "pagina" > < div id = "Menu" wicket:id = "menuPanel" > Menu </ div > < div id = "Content" wicket:id = "content" > Content </ div > </ div > < div id = "piedipagina" wicket:id = "footerPanel" > piedipagina </ div > </ body > </ html >
  • 21. Demo
  • 22. 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 = "Content-Type" content = "text/html; charset=UTF-8" > < title > Insert title here </ title > <wicket:head> <script>...</script> <wicket:head> ... </ head > < body > ... < wicket:panel > … </ wicket:panel > ...
  • 23. Il framework Wicket Pagine come oggetti
  • 24. 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( "contentComponent" , "L'ereditariatà  delle pagine Wicket e sia a livello di codice che di html" )); } }
  • 25. Pagina “figlia” del template Per la pagina figlia non è stato necessario creare un HTML . Abbiamo solo “personalizzato” il contenuto. addOrReplace( new Label( "contentComponent" , "L'ereditariatà  delle pagine Wicket e sia a livello di codice che di html" ));
  • 26. Il framework Wicket I link e lo stato delle pagine
  • 27. 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( "link" ) { @Override public void onClick() { } });
  • 28. 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( "link" ) { @Override public void onClick() { setResponsePage(JugTemplate.class); } });
  • 29. 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!
  • 30. 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().
  • 31. Codice della pagina di esempio public class HomePage extends WebPage { public HomePage (){ super (); add( new Label( "label" , "Hello World" )); add( new Label( "timeStamp" , "" + new Date())); add( new Link( "link" ) { @Override public void onClick() { } }); add( new Link( "spanLink" ){ @Override public void onClick() { } } ); .... @Override protected void onBeforeRender () { super .onBeforeRender(); addOrReplace( new Label( "timeStampFresh" , "" + new Date())); } }
  • 32. Il framework Wicket Il model dei componenti Wicket
  • 33. 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); }
  • 34. 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( "label" , "Hello World" )); ... 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>( "label" ); … new Model<Persona>( new Persona( “Mario” , “Rossi” )); …
  • 35. 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 = "form" > ... 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.
  • 36. 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 = "text" wicket:id = "username" />
  • 37. Prototipo maschera di login
  • 38. Il pannello di login (HTML) < html > … < wicket:panel > < div style = "margin: auto; width: 40%" class = "crop_content_contenuti" > < form id = "ricerca" method = "get" wicket:id = "form" > < fieldset id = "ricerca1" class = "center" > < legend wicket:id = "message" > Ricerca </ legend > < p wicket:id = "loginStatus" style = "font-weight: bold;color: red;text-align: left" ></ p > < span > Username: </ span > < input wicket:id = "username" type = "text" id = "username" />< br /> < span > Password: </ span > < input wicket:id = "password" type = "password" id = "password" /> < p > < input type = "submit" name = "login" value = "login" /> </ 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.
  • 39. 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( "form" ); 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.
  • 40. 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( "username" , new Model<String>( "" )); passwordField = new PasswordTextField( "password" , new Model<String>( "" )); loginStatus = new Label( "loginStatus" ); add( usernameField ); add( passwordField ); add( new Label( "message" , "Login" )); add( loginStatus ); } public final void onSubmit() { String username = usernameField .getValue(); String password = passwordField .getValue(); if ((username.equals( "Mario" ) && password.equals( "Rossi" ))) loginStatus .setDefaultModel( new Model<String>( "Complimenti!" )); else loginStatus .setDefaultModel( new Model<String>( "Username o password errate!" )); } 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.
  • 41. Il pannello di login (Java) public class LoginPanel extends Panel { public LoginPanel(String id) { super (id); init(); } private void init(){ Form loginForm = new LoginForm( "form" ); 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( "username" , new Model<String>( "" )); passwordField = new PasswordTextField( "password" , new Model<String>( "" )); loginStatus = new Label( "loginStatus" ); add( usernameField ); add( passwordField ); add( new Label( "message" , "Login" )); add( loginStatus ); } public final void onSubmit() { String username = usernameField .getValue(); String password = passwordField .getValue(); if ((username.equals( "Mario" ) && password.equals( "Rossi" ))) loginStatus .setDefaultModel( new Model<String>( "Complimenti!" )); else loginStatus .setDefaultModel( new Model<String>( "Username o password errate!" )); ... 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.
  • 42. 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( "contentComponent" )); } }
  • 43. Demo
  • 44. Il framework Wicket Gestione avanzata dello stato I repeat viewer
  • 45. 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.
  • 46. 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; } }
  • 47. 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>( "person.name" )); add( new TextField<String>( "person.sureName" )); add( new TextField<String>( "person.address" )); add( new TextField<String>( "person.email" )); } @Override protected void onSubmit() { super .onSubmit(); personsArray .add( person ); person = new Person(); } }
  • 48. 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>( "person.name" )); add( new TextField<String>( "person.sureName" )); add( new TextField<String>( "person.address" )); add( new TextField<String>( "person.email" )); } @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
  • 49. Il pannello < wicket:panel > < div style = "text-align: center;float: left;" > < form wicket:id = "form" id = "form" > ... </ form > </ div > < br style = "clear: both;" ></ br > < span wicket:id = "persons" > < div style = "background-color: rgb(255, 245, 236); border: " > < b > Nome : </ b > < span wicket:id = "personName" ></ span >< br ></ br > < b > Cognome : </ b > < span wicket:id = "personSurename" ></ span >< br ></ br > < b > Indirizzo : </ b > < span wicket:id = "address" ></ span >< br ></ br > < b > Cognome : </ b >< span wicket:id = "email" ></ 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.
  • 50. 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( "form" )); PageableListView<Person> persons = new PageableListView<Person>( "persons" , personsArray,30) { @Override protected void populateItem(ListItem<Person> personHtml) { personHtml.add( new Label( "personName" , personHtml.getModel().getObject().getName())); personHtml.add( new Label( "personSurename" , personHtml.getModel().getObject().getSureName())); personHtml.add( new Label( "address" , personHtml.getModel().getObject().getAddress())); personHtml.add( new Label( "email" , personHtml.getModel().getObject().getEmail())); } }; add(persons); this . personsArray = personsArray; } Il codice nell'ellisse è il repeat viewer che visualizza la lista di persone create
  • 51. Demo
  • 52. Conclusioni Pro: Permette di applicare la programmazione OO dal backend alla GUI, quindi... Rende le applicazioni web testabili molto più facilmente. Gestione dello stato trasparente. Grande varietà di componenti pronti all'uso. ... Contro: Cambio di prospettiva radicale! Documentazione utente e tutorial frammentari e scarni. ...
  • 53. Appendice “ Nascondere” i componenti Applicare attributi ai tag HTML
  • 54. 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( "sconto" , "Sconto merce" +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!
  • 55. 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( "warning" , "Attenzione!" ); warning.add( new SimpleAttributeModifier( "style" , "color:red;" ));
  • 56. Grazie ! Andrea Del Bene JUG Marche - www.jugancona.it