04 Tapestry5 In Action Pratica
-
Upload
bobpuley -
Category
Technology
-
view
914 -
download
1
Transcript of 04 Tapestry5 In Action Pratica
PraticaTapestry5 in action
Indice
Preparare l'ambiente
Creiamo la nostra prima page
Creiamo un componente per gestire il layout
Creiamo un componente per il login/logout
La pagina di iscrizione utente
L'upload di un file
Realizziamo il jukebox
Preparare l'ambiente
Tapestry5 in action
Preparare l'ambiente
Software utilizzato:
JDK 1.6 (mustang)
Servlet specification 2.4
Maven2
Eclipse 3.2
Maven2 plugin
Jetty launcher 1.4.1
Jetty 4.2.27
Mysql Server 5.0
Preparare l'ambiente
Prima di cominciare installiamo nel repository (locale) di maven tre jar previa scaricati:
jukemodel-1.0.0.jar (allegato alla presentazione)
jid3lib-0.5.4.jar, JLayer(mp3 util, reperibili qui e qui)
jta-1.0.1B.jar (java transaction api, reperibile qui)
mvn install:install-file -DgroupId=jukemodel -DartifactId=jukemodel -Dversion=1.0.0 -Dpackaging=jar -Dfile=/jarfile/path -DpomFile=/pomfile/path
mvn install:install-file -DgroupId=javax.transaction -DartifactId=jta -Dversion=1.0.1B -Dpackaging=jar -Dfile=/jarfile/path
mvn install:install-file -DgroupId=jid3lib -DartifactId=jid3lib -Dversion=0.5.4 -Dpackaging=jar -Dfile=/jarfile/path
mvn install:install-file -DgroupId=JLayer -DartifactId=JLayer -Dversion=1.0.0 -Dpackaging=jar -Dfile=/jarfile/path
Preparare l'ambiente
Ok, apriamo eclipse creiamo il nostro maven2 project jukeweb
File -> new -> project
Maven2 -> Maven2 project
Preparare l'ambiente
Create project:
Preparare l'ambiente
Configure project:
Preparare l'ambiente
Creato il progetto aggiungiamo le dipendenze:
jukemodel jukemodel 1.0.0 org.apache.tapestry tapestry-spring 5.0.6 org.springframework spring-web 2.0.2
Preparare l'ambiente
Ora dovremmo avere tutte le librerie necessarie.
Non ci resta che creare e configurare il web.xml
[...]
tapestry.app-packagejavaday.jukebox.web
jukeorg.apache.tapestry.TapestryFilter
juke/*
[...]
Creiamo la nostra prima page
Tapestry5 in action
Creiamo la nostra prima page
Start.java:
package javaday.jukebox.web.pages;
public class Start {
}
Creiamo la nostra prima page
Start.tml:
home page
Benvenuti nel mondo di Tapestry!
E' stata renderizzata la pagina ${class.simpleName}!
Creiamo la nostra prima page
Start.tml:
home page
Benvenuti nel mondo di Tapestry!
E' stata renderizzata la pagina ${class.simpleName}!
Creiamo la nostra prima page
La sintassi ${[prefix:]expression[.nestedExpr]} detta Expansions.
In un' expansions:
L'espressione passata viene interpretata secondo le regole di binding
La regola da usare viene selezionata con un prefisso
prop (default)
literal
message
Creiamo la nostra prima page
Bene, giunto il momento di lanciare per la prima volta l'applicazione:
Creiamo la nostra prima page
Configuriamo jetty:
Creiamo la nostra prima page
Configuriamo e lanciamo jetty:
Creiamo la nostra prima page
Infine digitiamo l'url sul browser:
http://localhost:8080/jukeweb/
Creiamo un componente per
gestire il layout
Tapestry5 in action
Creiamo un componente..
Prima di proseguire occorre includere nel progetto (in src/main/webapp/) alcune risorse disponibili come allegati alla presentazione:
Stylesheets
Immagini
Un flash mp3 player
E in src/main/resources/
Javascript files
Creiamo un componente..
Come gi detto le component classes e i component templates si devono trovare in qualunque sub-package di
tapestry.app-package/components
Creiamo quindi un componente che ci consenta di centralizzare la gestione del layout delle pagine
Creiamo un componente..
Border.java (versione 1)
package javaday.jukebox.web.components;
public class Border {
}
Creiamo un componente..
Border.tml (versione 1)
titolo finestra
...
Creiamo un componente..
Border.tml (versione 1)
...
titolo paginamenu Created by [email protected]
Creiamo un componente..
Border.tml (versione 1)
...
titolo paginamenu Created by [email protected]
Creiamo un componente..
Adeguiamo quindi il template Start.tml
Benvenuti nel mondo di Tapestry!
E' stata renderizzata la pagina ${class.simpleName}!
Creiamo un componente..
http://localhost:8080/jukeweb/
Creiamo un componente..
Ok, ora dovremmo avere acquisito un po' di confidenza col codice, ma il tutto ancora statico
Prima di tutto vediamo come fare a passare al Border i titoli per la finestra e per la pagina.
Creiamo un componente..
Un parametro di un componente altro non che un'attributo d'istanza opportunamente annotato (@Parameter) e corredato dei metodi accessor.
Creiamo un componente..
Border.java (versione 2)
package javaday.jukebox.web.components;
import org.apache.tapestry.annotations.Parameter;
public class Border {@Parameter(defaultPrefix="literal")private String windowTitle = "Untitled";
@Parameter(defaultPrefix="literal")private String pageTitle = "Untitled";
...
Creiamo un componente..
Border.java (versione 2)
package javaday.jukebox.web.components;
import org.apache.tapestry.annotations.Parameter;
public class Border {@Parameter(defaultPrefix="literal")private String windowTitle = "Untitled";
@Parameter(defaultPrefix="literal")private String pageTitle = "Untitled";
...Binding prefix:
prop
literal
asset
block
component
traslate
Message
validate
Creiamo un componente..
Border.java (versione 2)
...public String getPageTitle() {return pageTitle;}
public void setPageTitle(String pageTitle) {this.pageTitle = pageTitle;}
public String getWindowTitle() {return windowTitle;}
public void setWindowTitle(String windowTitle) {this.windowTitle = windowTitle;}
}
Creiamo un componente..
Adeguiamo quindi il template Start.tml
Benvenuti nel mondo di Tapestry!
E' stata renderizzata la pagina ${class.simpleName}!
Creiamo un componente..
http://localhost:8080/jukeweb/
Creiamo un componente..
Gli Assets
sono il meccanismo offerto da Tapestry per riferirsi a risorse statiche
Consentono di accedere a risorse presenti nel classpath (default) o nel context root della web application
Creiamo un componente..
Creiamo quindi ora in Border.java i riferimenti agli stylesheets, ai files javascript e al mp3 flash player
Per farlo dobbiamo
Dichiarare per ciascuna risorsa che vogliamo linkare una variabile d'istanza di tipo org.apache.tapestry.Asset e il corrispondente metodo getter (il setter non occorre in quanto la risorsa in sola lettura)
Creiamo un componente..
(continua)
Annotare ciascuna delle variabili con org.apache.tapestry.ioc.annotations.Inject
Annotare ciascuna delle variabili con org.apache.tapestry.annotations.Path (@Path(context|classpath:path/risorsa.ext))
Creiamo un componente..
Aggiungiamo a Border.java
...@Inject@Path("context:styles/layout.css")private Asset layout;@Inject@Path("context:styles/header.css")private Asset header;@Inject@Path("context:styles/menu.css")private Asset menu;@Inject@Path("context:styles/body.css")private Asset body;...
Creiamo un componente..
(...continua)
...@Inject@Path("classpath:js/script.js")private Asset script;@Inject@Path("classpath:js/audio-player.js")private Asset playerScript;
...
Creiamo un componente..
Aggiungiamo i metodi getter e modifichiamo il template
...
${windowTitle}
...
Creiamo un componente..
Dopo aver salvato ed eseguito diamo uno sguardo al codice risultante
......
Creiamo un componente..
Creiamo un componente per il men. Menu.java
package javaday.jukebox.web.components;
import org.apache.tapestry.annotations.OnEvent;
public class Menu {
@OnEvent(value="action")String openPage(String pageName){return pageName;}}
Creiamo un componente..
Creiamo un componente per il men. Menu.java
package javaday.jukebox.web.components;
import org.apache.tapestry.annotations.OnEvent;
public class Menu {
@OnEvent(value="action")String openPage(String pageName){return pageName;}}
Creiamo un componente..
E il template Menu.tml
Home
Creiamo un componente..
E il template Menu.tml
Home
Creiamo un componente per
il login/logout
Tapestry5 in action
Il componente login
Passiamo ora a creare un componente che gestisca le operazioni di login/logout
Al componente spettano la responsabilit di:
esporre le operazioni opportune
Conoscere e gestire il comportamento dell'applicazione al momento del login/logout
Il componente login
Login.java
package javaday.jukebox.web.components;...public class Login {
@Persist private String _userName;
private String _password;
@Component(id = "password") private PasswordField _passwordField;
@Component(id="loginForm") private Form _form;...
Il componente login
Login.java
package javaday.jukebox.web.components;...public class Login {
@Persist private String _userName;
private String _password;
@Component(id = "password") private PasswordField _passwordField;
@Component(id="loginForm") private Form _form;...
Il componente login
Login.java
package javaday.jukebox.web.components;...public class Login {
@Persist private String _userName;
private String _password;
@Component(id = "password") private PasswordField _passwordField;
@Component(id="loginForm") private Form _form;...
Il componente login
(... continua)
...@OnEvent(component="loginForm",value="success") void login() {boolean valid = false;if(!valid){ _form.recordError(_passwordField, "Invalid user name or password.");} }
@OnEvent(component="logout",value="action")void logout(){}...
Il componente login
(... continua)
...@OnEvent(component="loginForm",value="success") void login() {boolean valid = false;if(!valid){ _form.recordError(_passwordField, "Invalid user name or password.");} }
@OnEvent(component="logout",value="action")void logout(){}...
Il componente login
(... continua)
...@OnEvent(component="loginForm",value="success") void login() {boolean valid = false;if(!valid){ _form.recordError(_passwordField, "Invalid user name or password.");} }
@OnEvent(component="logout",value="action")void logout(){}...
Il componente login
(... continua)
...
public String getPassword() {return _password;}public void setPassword(String _password) {this._password = _password;}public String getUserName() {return _userName;}public void setUserName(String name) {_userName = name;}}
Il componente login
Login.tml
Loginuser...
Il componente login
Login.tml
Loginuser...
Il componente login
Login.tml
Loginuser...
Il componente login
Login.tml
Loginuser...
Il componente login
(..continua)
...passlogout
Il componente login
(..continua)
...passlogout
Il componente login
(..continua)
...passlogout
Il componente login
E' giunto il momento di integrare spring e il backend per comunicare con il database
Primo, modificare il filter nel web.xml
[...]
jukeorg.apache.tapestry.spring.TapestrySpringFilter
[...]
Il componente login
Secondo, aggiungere al web.xml:
Il listener di spring che si vuole usare
Il context-param che punta ai files di configurazione
[...]
contextConfigLocation/WEB-INF/config/bean.xml,/WEB-INF/config/hibernate-config.xml
org.springframework.web.context.ContextLoaderListener
[...]
Il componente login
Importiamo nel path opportuno i due files di configurazione di spring
Modifichiamo i dati per la connessione nel file hibernate-config.xml
[...][...]
Il componente login
Importiamo nel path opportuno i due files di configurazione di spring
Modifichiamo i dati per la connessione nel file hibernate-config.xml
[...][...]
Il componente login
Per conservare lo stato dell'utente creiamo una classe UserState nel package
tapestry.app-package/state
package javaday.jukebox.web.state;import javaday.jukebox.model.dto.User;public class UserState {private User user;public User getUser() {return user;}public void setUser(User user) {this.user = user;}public boolean isLoggedIn(){return user != null && user.getId() != null;}}
Il componente login
Aggiungiamo i riferimenti allo state object e allo userService, e il metodo getter per accedere allo state object in Login.java
...@ApplicationStateprivate UserState _userState;
@Injectprivate IUserService _userService;
public UserState getUserState() {return _userState;}
...
Il componente login
Aggiungiamo i riferimenti allo state object e allo userService, e il metodo getter per accedere allo state object in Login.java
...@ApplicationStateprivate UserState _userState;
@Injectprivate IUserService _userService;
public UserState getUserState() {return _userState;}
...
Il componente login
Aggiungiamo i riferimenti allo state object e allo userService, e il metodo getter per accedere allo state object in Login.java
...@ApplicationStateprivate UserState _userState;
@Injectprivate IUserService _userService;
public UserState getUserState() {return _userState;}
...
Il componente login
Aggiungiamo i riferimenti allo state object e allo userService, e il metodo getter per accedere allo state object in Login.java
...@ApplicationStateprivate UserState _userState;
@Injectprivate IUserService _userService;
public UserState getUserState() {return _userState;}
...Per specificare il nome del bean da usare occorre modificare il codice come segue:
@Inject@Service("userService")private IUserService _userService;
Il componente login
Modifichiamo i metodi login e logout in Login.java
...@OnEvent(component="loginForm",value="success")void login(){_userState.setUser(_userService.login(getUserName(), getPassword()));if(!_userState.isLoggedIn()){ _form.recordError(_passwordField, "Invalid user name or password.");}}@OnEvent(component="logout",value="action")void logout(){_userState.setUser(null);}...
Il componente login
Ora con il tapestry component If facciamo in modo che nel template Login.tml venga mostrato il form di login solo se non ci si loggati e l'inverso per il comando di logout.
L'If component ha la seguente forma:
renderizzato se test=true e negate=false, oppure test=false e negate=truealtrimenti renderizza questo
Il componente login
Il Login.tml diventa quindi:
[...]logout
Il componente login
Adesso, per verificare quanto realizzato inseriamo un utente di prova sul db
insert into user (user, pass, firstName, name, emailAddress, birthDate)values ('bobpuley', 'bobpuley', 'pugliese', 'marco', '[email protected]', '1973-02-24');
Il componente login
Login:
Il componente login
Login:
La pagina di iscrizione utente
Tapestry5 in action
La pagina d'iscrizione utente
Veniamo ora a esaminare un componente molto potente, il beanEditForm.
La pagina d'iscrizione utente
Il beanEditForm:
Accetta i seguenti parametri:
object: l'oggetto che si vuole editare
remove: una lista di nomi di attributi dell'oggetto da editare, di cui si vuol inibire il rendering
submitLabel: l'etichetta del submit button del form
model: un'istanza di org.apache.tapestry.beaneditor.BeanModel
reorder: una lista di nomi di attributi nell'ordine desiderato
clientValidation: true|false
La pagina d'iscrizione utente
Il beanEditForm:
mappa
Boolean con checkbox
java.util.Date con DateField
Enum con select
String e Number con textField
La pagina d'iscrizione utente
Il beanEditForm:
mappa
Boolean con checkbox
java.util.Date con DateField
Enum con select
Tipi primitivi, wrapper e String con textField
Pu essere ulteriormente configurato annotando opportunamente l'oggetto che gli si passa.
La pagina d'iscrizione utente
Aggiungiamo il package account all'interno della root delle page component classes e creaiamo la classe CreateAccount.java
package javaday.jukebox.web.pages.account;import javaday.jukebox.model.dto.User;import org.apache.tapestry.annotations.OnEvent;public class CreateAccount {
private User user = new User();
public User getUser() {return user;}public void setUser(User user) {this.user = user;}
@OnEvent(component="userForm", value="success")void menageAccount(){System.out.println(user);}}
La pagina d'iscrizione utente
Aggiungiamo il package account all'interno della root delle page component classes e creaiamo la classe CreateAccount.java
package javaday.jukebox.web.pages.account;import javaday.jukebox.model.dto.User;import org.apache.tapestry.annotations.OnEvent;public class CreateAccount {
private User user = new User();
public User getUser() {return user;}public void setUser(User user) {this.user = user;}
@OnEvent(component="userForm", value="success")void menageAccount(){System.out.println(user);}}
La pagina d'iscrizione utente
...e il template.
Pass
La pagina d'iscrizione utente
...e il template.
Pass
La pagina d'iscrizione utente
...e il template.
reorder="user,pass,firstName,name,birthDate,emailAddress">Pass
La pagina d'iscrizione utente
...e il template.
reorder="user,pass,firstName,name,birthDate,emailAddress">Pass
La pagina d'iscrizione utente
http://localhost:8080/jukeweb/account/create
La pagina d'iscrizione utente
Come forse avrete notato la url non come ci si aspetterebbe /account/createaccount, bens /account/create. In sostanza tapestry ignora la ripetizione di account, questo consente di avere url pi pulite.
Resta da realizzare un link per accedere alla pagina di iscrizione, e aggiungere un riferimento al servizio verso il db nella classe della pagina per salvare l'utente creato.
La pagina d'iscrizione utente
Login.tml
[...]
Loginuserpassor: Get an account
[...]
La pagina d'iscrizione utente
CreateAccount.java
package javaday.jukebox.web.pages.account;import javaday.jukebox.model.dto.User;import org.apache.tapestry.annotations.OnEvent;public class CreateAccount {
private User user = new User();@Injectprivate IUserService userService;
public User getUser() {return user;}public void setUser(User user) {this.user = user;}
@OnEvent(component="userForm", value="success")void menageAccount(){userService.create(user);}}
La pagina d'iscrizione utente
CreateAccount.java
package javaday.jukebox.web.pages.account;import javaday.jukebox.model.dto.User;import org.apache.tapestry.annotations.OnEvent;public class CreateAccount {
private User user = new User();@Injectprivate IUserService userService;
public User getUser() {return user;}public void setUser(User user) {this.user = user;}
@OnEvent(component="userForm", value="success")void menageAccount(){userService.create(user);}}
La pagina d'iscrizione utente
CreateAccount.java
package javaday.jukebox.web.pages.account;import javaday.jukebox.model.dto.User;import org.apache.tapestry.annotations.OnEvent;public class CreateAccount {
private User user = new User();@Injectprivate IUserService userService;
public User getUser() {return user;}public void setUser(User user) {this.user = user;}
@OnEvent(component="userForm", value="success")void menageAccount(){userService.create(user);}}
L'upload di un file
Tapestry5 in action
L'upload di un file
Tapestry incapsula il componente e i servizi, necessari per effettuare l'upload, in un modulo a parte tapestry-upload.jar
Quindi aggiungiamo la dipendenza corrispondente nel pom.xml
[...]
org.apache.tapestry tapestry-upload 5.0.6
[...]
L'upload di un file
Creiamo una class page track/CreateTrack.java
public class CreateTrack {
private UploadedFile uploadedFile;
@OnEvent(component = "uploadForm", value = "success")public void upload() {FileUtil fileUtil = new FileUtil(null);File file = fileUtil.getTmpFile(uploadedFile.getFileName());uploadedFile.write(file);}public UploadedFile getUploadedFile() {return uploadedFile;}
public void setUploadedFile(UploadedFile uploadedFile) {this.uploadedFile = uploadedFile;}}
L'upload di un file
Quindi il template track/CreateTrack.tml
Upload a Mp3Add track
L'upload di un file
Una volta caricato il file dobbiamo inserire i dati ad essa relativi
Modifichiamo il metodo upload come segue
@OnEvent(component = "uploadForm", value = "success")public void upload() {FileUtil fileUtil = new FileUtil(null);File file = fileUtil.getTmpFile(uploadedFile.getFileName());uploadedFile.write(file);try {setTrack(fileUtil.getMp3Infos(file));setStyle(StylesEnum.getFromValue(getTrack().getStyle()));} catch (Exception e) {setTrack(new Track());}}
L'upload di un file
Una volta caricato il file dobbiamo inserire i dati ad essa relativi
Modifichiamo il metodo upload come segue
@OnEvent(component = "uploadForm", value = "success")public void upload() {FileUtil fileUtil = new FileUtil(null);File file = fileUtil.getTmpFile(uploadedFile.getFileName());uploadedFile.write(file);try {setTrack(fileUtil.getMp3Infos(file));setStyle(StylesEnum.getFromValue(getTrack().getStyle()));} catch (Exception e) {setTrack(new Track());}}
L'upload di un file
Una volta caricato il file dobbiamo inserire i dati ad essa relativi
Modifichiamo il metodo upload come segue
@OnEvent(component = "uploadForm", value = "success")public void upload() {FileUtil fileUtil = new FileUtil(null);File file = fileUtil.getTmpFile(uploadedFile.getFileName());uploadedFile.write(file);try {setTrack(fileUtil.getMp3Infos(file));setStyle(StylesEnum.getFromValue(getTrack().getStyle()));} catch (Exception e) {setTrack(new Track());}}
L'upload di un file
Aggiungiamo un attributo Track con i relativi accessor, per editare le informazioni.
@Persistprivate Track track = null;public Track getTrack() {return track;}
public void setTrack(Track track) {this.track = track;}
L'upload di un file
Occorre anche definire un attributo StylesEnum
Essendo una enum, il beanEditForm la gestir con una select.
@Persistprivate StylesEnum style;public StylesEnum getStyle() {return style;}
public void setStyle(StylesEnum style) {this.style = style;}
L'upload di un file
Infine ci servono i riferimenti allo stateObject e al servizio per salvare la traccia creata
@Injectprivate ITrackService trackService;@ApplicationStateprivate UserState state;
@OnEvent(component = "trackForm", value = "success")public void saveTrack() {try {track.setUser(state.getUser());track.setStyle(getStyle().toString());trackService.create(getTrack());track.setFileName(new FileUtil(null).modifyTrack(track));trackService.modify(track);setTrack(null);setStyle(null);} catch (Exception e) {e.printStackTrace();}}
L'upload di un file
Infine ci servono i riferimenti allo stateObject e al servizio per salvare la traccia creata
@Injectprivate ITrackService trackService;@ApplicationStateprivate UserState state;
@OnEvent(component = "trackForm", value = "success")public void saveTrack() {try {track.setUser(state.getUser());track.setStyle(getStyle().toString());trackService.create(getTrack());track.setFileName(new FileUtil(null).modifyTrack(track));trackService.modify(track);setTrack(null);setStyle(null);} catch (Exception e) {e.printStackTrace();}}
L'upload di un file
Infine ci servono i riferimenti allo stateObject e al servizio per salvare la traccia creata
@Injectprivate ITrackService trackService;@ApplicationStateprivate UserState state;
@OnEvent(component = "trackForm", value = "success")public void saveTrack() {try {track.setUser(state.getUser());track.setStyle(getStyle().toString());trackService.create(getTrack());track.setFileName(new FileUtil(null).modifyTrack(track));trackService.modify(track);setTrack(null);setStyle(null);} catch (Exception e) {e.printStackTrace();}}
L'upload di un file
Infine ci servono i riferimenti allo stateObject e al servizio per salvare la traccia creata
@Injectprivate ITrackService trackService;@ApplicationStateprivate UserState state;
@OnEvent(component = "trackForm", value = "success")public void saveTrack() {try {track.setUser(state.getUser());track.setStyle(getStyle().toString());trackService.create(getTrack());track.setFileName(new FileUtil(null).modifyTrack(track));trackService.modify(track);setTrack(null);setStyle(null);} catch (Exception e) {e.printStackTrace();}}
L'upload di un file
Infine ci servono i riferimenti allo stateObject e al servizio per salvare la traccia creata
@Injectprivate ITrackService trackService;@ApplicationStateprivate UserState state;
@OnEvent(component = "trackForm", value = "success")public void saveTrack() {try {track.setUser(state.getUser());track.setStyle(getStyle().toString());trackService.create(getTrack());track.setFileName(new FileUtil(null).modifyTrack(track));trackService.modify(track);setTrack(null);setStyle(null);} catch (Exception e) {e.printStackTrace();}}
L'upload di un file
Infine dobbiiamo modificare il template, in modo da mostrare prima l'upload form, e poi il track form.
[...]form uploadEdit infoPass[...]
L'upload di un file
Infine dobbiiamo modificare il template, in modo da mostrare prima l'upload form, e poi il track form.
[...]form uploadEdit infoPass[...]
L'upload di un file
Infine dobbiiamo modificare il template, in modo da mostrare prima l'upload form, e poi il track form.
[...]form uploadEdit infoPass[...]
L'upload di un file
Infine dobbiiamo modificare il template, in modo da mostrare prima l'upload form, e poi il track form.
[...]form uploadEdit infoPass[...]
Realizziamo il jukebox
Tapestry5 in action
Realizziamo il jukebox
Bene, siamo giunti all'ultimo elemento dell'applicazione
Nel realizzarlo vedremo
come untilizzare il grid component
Realizziamo il jukebox
Bene, siamo giunti all'ultimo elemento dell'applicazione
Nel realizzarlo vedremo
come untilizzare il grid component
come realizzare un componente che scrive direttamente sull'output (privo di template)
Realizziamo il jukebox
Bene, siamo giunti all'ultimo elemento dell'applicazione
Nel realizzarlo vedremo
come untilizzare il grid component
come realizzare un componente che scrive direttamente sull'output (privo di template)
come ottenere uno stream verso una risorsa tramite Tapestry
Realizziamo il jukebox
Modifichiamo quindi la Start page, e aggiungiamole gli attributi
@Persistprivate List tracks = new ArrayList();
private Track itemTrack;
@Injectprivate ITrackService service;
public Track getItemTrack() {return itemTrack;}public void setItemTrack(Track itemTrack) {this.itemTrack = itemTrack;}
public List getTracks() {return tracks;}public void setTracks(List tracks) {this.tracks = tracks;}
Realizziamo il jukebox
Modifichiamo quindi la Start page, e aggiungiamole gli attributi
@Persistprivate List tracks = new ArrayList();
private Track itemTrack;
@Injectprivate ITrackService service;
public Track getItemTrack() {return itemTrack;}public void setItemTrack(Track itemTrack) {this.itemTrack = itemTrack;}
public List getTracks() {return tracks;}public void setTracks(List tracks) {this.tracks = tracks;}
Realizziamo il jukebox
Infine faccio in modo che quando la pagina viene inizializzata, carichi dal database le tracce.
@SetupRendervoid init(){setTracks(service.findAll());if(getTracks()==null || getTracks().isEmpty()){setTracks(new ArrayList());}}
Realizziamo il jukebox
Infine faccio in modo che quando la pagina viene inizializzata, carichi dal database le tracce.
@SetupRendervoid init(){setTracks(service.findAll());if(getTracks()==null || getTracks().isEmpty()){setTracks(new ArrayList());}}
Realizziamo il jukebox
Quindi inseriamo il component grid nel template
Benvenuti nel mondo di Tapestry!
E' stata renderizzata la pagina ${class.simpleName}!JukeBoxThe
collection is empty.
Realizziamo il jukebox
Riordiniamo gli attributi
Benvenuti nel mondo di Tapestry!
E' stata renderizzata la pagina ${class.simpleName}!JukeBoxThe
collection is empty.
Realizziamo il jukebox
Aggiungiamo la paginazione
Benvenuti nel mondo di Tapestry!
E' stata renderizzata la pagina ${class.simpleName}!JukeBoxThe
collection is empty.
Realizziamo il jukebox
Gestiamo il rating con un componente specifico
Benvenuti nel mondo di Tapestry!
E' stata renderizzata la pagina ${class.simpleName}!JukeBoxThe
collection is empty.
Realizziamo il jukebox
Il componente Rating.java
public class Rating {private static final String MAX_RATING = "*****";@Parameter(required=true)private Integer ratingValue;@BeginRendervoid render(MarkupWriter writer){int rating = calculateRating(ratingValue);writer.element("span","class","rating" + rating);writer.write(getRatingStars(rating));writer.end();}
...
Realizziamo il jukebox
Il componente Rating.java
public class Rating {private static final String MAX_RATING = "*****";@Parameter(required=true)private Integer ratingValue;@BeginRendervoid render(MarkupWriter writer){int rating = calculateRating(ratingValue);writer.element("span","class","rating" + rating);writer.write(getRatingStars(rating));writer.end();}
...
Realizziamo il jukebox
Il componente Rating.java
public class Rating {private static final String MAX_RATING = "*****";@Parameter(required=true)private Integer ratingValue;@BeginRendervoid render(MarkupWriter writer){int rating = calculateRating(ratingValue);writer.element("span","class","rating" + rating);writer.write(getRatingStars(rating));writer.end();}
...
Realizziamo il jukebox
Il componente Rating.java
public class Rating {private static final String MAX_RATING = "*****";@Parameter(required=true)private Integer ratingValue;@BeginRendervoid render(MarkupWriter writer){int rating = calculateRating(ratingValue);writer.element("span","class","rating" + rating);writer.write(getRatingStars(rating));writer.end();}
...
Realizziamo il jukebox
Il componente Rating.java
public class Rating {private static final String MAX_RATING = "*****";@Parameter(required=true)private Integer ratingValue;@BeginRendervoid render(MarkupWriter writer){int rating = calculateRating(ratingValue);writer.element("span","class","rating" + rating);writer.write(getRatingStars(rating));writer.end();}
...
Realizziamo il jukebox
Il componente Rating.java
public Integer getRatingValue() {return ratingValue;}
public void setRatingValue(Integer value) {this.ratingValue = value;}private String getRatingStars(int rating) {return MAX_RATING.substring(0, rating);}private int calculateRating(Integer value) {int rating = (int)(value/5) + 1;rating = rating