Atelier
ObjectifCréation une application basic avec GWT pour familiarise avec le Framework                                  Descri...
Les éléments dinterface utilisateur: une table pour contenir les données de stock deux boutons, lun pour ajouter des act...
Création du projet GWT avec Maven
Client serveur communication RPC  Principe de fonctionnement                                                             ...
Interface synchrone coté client               Spécification de vos servicesImport com.google.gwt.user.client.rpc.RemoteS...
Appel de méthodes asynchrones   o Un appel de méthode asynchrone nécessite de passer un objet de     rappel (callback obj...
• Le chemin d’accès à un service est composé de deux parties– /nomDuModule/nomDuService• Le nom du service peut être défin...
3 public interface MonService extends RemoteService {4     String exempleMethode();5}      Toutes vos méthodes asynchrones...
1 //MonServiceAsync.java2 public interface MonServiceAsync {34     void exempleMethode(AsyncCallback<String> callback);56}...
0607 <servlet-mapping>08   <servlet-name>monServiceImpl</servlet-name>09   <url-pattern>/ma_premiere_application/monservic...
05           public void onFailure(Throwable caught) {    06               Window.alert("Erreur lors de lappel serveur"); ...
34           @Override5           public void onClick(ClickEvent event) {6               monService.exempleMethode(callbac...
/**  * Entry point method.  */ public void onModuleLoad() {   // Create table for stock data.   stocksFlexTable.setText(0,...
Window.alert("" + symbol + " is not a valid symbol.");              newSymbolTextBox.selectAll();              return;    ...
StockPrice[] prices = new StockPrice[stocks.size()];          for (int i = 0; i < stocks.size(); i++) {           double p...
Atelier gwt
Prochain SlideShare
Chargement dans…5
×

Atelier gwt

560 vues

Publié le

Bon document pour s'initier avec GWT

Publié dans : Technologie
0 commentaire
0 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

  • Soyez le premier à aimer ceci

Aucun téléchargement
Vues
Nombre de vues
560
Sur SlideShare
0
Issues des intégrations
0
Intégrations
2
Actions
Partages
0
Téléchargements
9
Commentaires
0
J’aime
0
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

Atelier gwt

  1. 1. Atelier
  2. 2. ObjectifCréation une application basic avec GWT pour familiarise avec le Framework DescriptionDans ce TP on vas crée une application StockWatcher les principesfonctionnements de l’application sont :  Permet aux utilisateurs la possibilité dajouter des actions  Afficher les informations suivantes pour chaque stock: symbole, le cours, le changement depuis le dernier rafraîchissement  Fournir aux utilisateurs la possibilité de supprimer un support dans la liste Actualiser le prix des actions  Calculer la variation depuis la dernière actualisation à la fois comme un nombre et un pourcentage  Afficher un horodatage indiquant la dernière mise à jour
  3. 3. Les éléments dinterface utilisateur: une table pour contenir les données de stock deux boutons, lun pour ajouter des actions et un pour les supprimer une zone de saisie pour entrer le code de stock un timestamp pour afficher lheure et la date de la dernière actualisation Les étapes de créations de l’application Creation d’un nouveau projet création d’interface utilisateur manager les événements debug l’application application d’un style (css) complies l’application client-serveur communication (RPC) Ajout du plugin mojo
  4. 4. Création du projet GWT avec Maven
  5. 5. Client serveur communication RPC Principe de fonctionnement Code GWTOn demande un service maison n’attend pas la réponse Interface asynchroneCelle-ci viendra en sontemps grâce à un « objet derappel ». Interface synchrone Code Serveur Créer un service  Coté client, définir une interface dite synchrone qui étend RemoteService et qui liste toutes les méthodes RPC  Coté serveur, implémenter l’interface et étendre RemoteServiceServlet  Coté client, définir une interface asynchrone basée sur la première interface avec le même nombre de méthodes que la première interface
  6. 6. Interface synchrone coté client  Spécification de vos servicesImport com.google.gwt.user.client.rpc.RemoteService;public interface MyService extends RemoteService {public T myMethod(T1 p1, T2 p2, T3 p3); } Implémentation coté serveur  Implémentation de vos servicespublic class MyServiceImpl extends RemoteServiceServletimplements MyService {public T myMethod(T1 p1, T2 p2, T2 p3) { // … return r; }} Interface asynchrone coté client  Implémentation de vos servicesinterface MyServiceAsync {public void myMethod(T1 p1, T2 p2,T2 p3,AsyncCallback<T> callback); }
  7. 7. Appel de méthodes asynchrones o Un appel de méthode asynchrone nécessite de passer un objet de rappel (callback object) o L’objet de rappel est notifié lorsque l’appel asynchrone est terminé o En attendant l’appelant continu son activité o Remarquez que les méthodes asynchrones ont un type résultat void o Conventions de nommage o Nom des classes et interfaces – MyService interface synchrone – MyServiceImpl implementation – MyServiceAsync interface asynchrone o Chaque méthode dans l’interface synchrone doit avoir une méthode correspondante dans l’interface asynchrone avec un paramêtre extra en dernier argument de type AsyncCallback o Méthode de l’interface synchronepublic Integer[ ] myMethod(String s, int i) o Méthode de l’interface asynchronepublic void myMethod(String s,int i, AsyncCallback<Integer[ ]> callback) Utilisation de services• Créer une instance de serviceMonServiceAsync monService = GWT.create(MonService.class);• Appel de méthode à distancemonService.maMethode(p1,p2, new AsyncCallBack<T>() { public onFailure(Trowable t) {...} public onSuccess(T result) {...}})Chemin d’accès à un service
  8. 8. • Le chemin d’accès à un service est composé de deux parties– /nomDuModule/nomDuService• Le nom du service peut être défini de deux manières– Statiquement par annotation dans l’interface synchrone@RemoteServiceRelativePath("service")– DynamiquementServiceAsync service = GWT.create(Service.class);ServiceDefTarget test = (ServiceDefTarget) servicetest.setServiceEntryPoint("/module/service");• Les déclarations de path pour la servlet doivent être cohérentes– Dans le descripteur de module<servlet class= "MaServlet" path="/module/service"/>– Dans le descripteur web.xml<url-pattern>/module/service</urlpattern> ApplicationDans ce mini tutorial nous allons creer une petite application qui implémente leservice propose par le framework GWT .Ceer un nouveau projet et suivre lesdiffférentes etapes decritent .I ConfigurationAfin de définir et configurer une interface RPC asynchrone, vous aurez besoinde créer trois nouveaux fichiers:1. MonServiceUne interface implémentant RemoteService dans laquelle vous définirez lesméthodes que vous voudrez appeler. Vous définirez grâce àl’annotation @RemoteServiceRelativePath(String path), le chemin grâce auquelvous accéderez à votre service:Cette classe doit etre créée dans le package client1 //MonService.java2 @RemoteServiceRelativePath("monservice")
  9. 9. 3 public interface MonService extends RemoteService {4 String exempleMethode();5} Toutes vos méthodes asynchrones doivent avoir un retour detype Serializable !2. MonServiceImplUne classe située dans le package server, étendant RemoteServiceServlet etimplémentant MonService, dont vous implémenterez les méthodes :1 //MonServiceImpl.java public class MonServiceImpl extends RemoteServiceServlet implements Mon2 Service {34 @Override5 public String exempleMethode() {6 return "Réponse du Serveur";7 }89}3. MonServiceAsyncUne interface devant être dans le même package que MonService et dont le nomdevra être le même que celle-ci suivi de Async (e.g :MonServiceAsync). Danscette interface, vous définirez les mêmes méthodes que dans MonService, mis apart quelques détails:
  10. 10. 1 //MonServiceAsync.java2 public interface MonServiceAsync {34 void exempleMethode(AsyncCallback<String> callback);56}Comme vous pouvez le voir, la méthode dans cette interface retourne void, doncrien. En effet, toutes vos méthodes dans cette interface auront un type deretour void. Cependant, le type de retour de vos méthodes définiesdans MonService se retrouvent dans l’argument supplémentaire de votreméthode : AsyncCallback<String> callback. Toutes vos méthodesdéfinies dans MonService devront donc être ainsi transposéesdansMonServiceAsync.Maintenant, afin de pouvoir accéder à notre code côté serveur, nous allons avoirbesoin de configurer une servlet qui contiendra l’implémentationde MonService dans le web.xml. Rien de différent ici avec la définitionhabituelle des servlets en Java. Vous préciserez donc la classe de la servlet, ainsique son chemin (celui définit dans MonService). <!--MonServiceAsync.java-->0102 <servlet>0 <servlet-name>monServiceImpl</servlet-name>3 <servlet-0 class>com.gwtfrance.mapremiereapplication.server.MonServiceImpl</servlet4 -class>05 </servlet>
  11. 11. 0607 <servlet-mapping>08 <servlet-name>monServiceImpl</servlet-name>09 <url-pattern>/ma_premiere_application/monservice</url-pattern>10 </servlet-mapping>Voilà, votre application est prête à utiliser les appels asynchrones. Si vous ledésirez, maintenant que vous savez à quoi servent lesfichiersGreetingService, GreetingServiceAsync, et GreetingServiceImpl, vouspouvez les supprimer, ainsi que la configuration de laservlet greetingServicedans le web.xml.II. UtilisationGWT-RPC étant configuré, nous allons pouvoir effectuer nos appelsasynchrones. Pour ceci, vous aurez besoin de créer une instance du proxy deservice :Créer une classe dans le package client qui implément leentryPoint :explement :Ma_Premiere_Application.java1 //Ma_Premiere_Application.java2 final MonServiceAsync monService = GWT.create(MonService.class);Je vous conseille fortement de faire de cette instance un Singleton, étant inutilede réinstancier systématiquement ce proxy.Afin de pouvoir gérer les retour de notre appel asynchrone, nous aurons besoind’un objet AsyncCallback.01 //Ma_Premiere_Application.java02 final AsyncCallback<String> callback = new AsyncCallback<String>() {04 @Override
  12. 12. 05 public void onFailure(Throwable caught) { 06 Window.alert("Erreur lors de lappel serveur"); 07 08 } 09 10 @Override 11 public void onSuccess(String result) { 12 Window.alert(result); 13 14 } 15 }; Comme vous pouvez le voir, lors de l’instanciation de notre objet callback, nous devons implémenter deux méthode: La méthode onFailure(Throwable caught) est appelée lorsque une erreur se produit côté serveur lors de votre appel. Grâce à l’objetThrowable, vous pourrez récupérer les exceptions lancées côté serveur et les traiter comme vous l’entendez. La méthode onSuccess(String result) est elle appelée lorsque le traitement serveur s’est passé sans problème. L’objet retourné correspond à l’objet retourné par votre implémentation côté serveur. Notre objet callback étant maintenant défini, nous pouvons donc effectuer notre appel asynchrone. Ici, nous remplaçons le code de la méthodeonClick(Event event) par notre appel: 1 //Ma_Premiere_Application.java 2 monBouton.addClickHandler(new ClickHandler() {
  13. 13. 34 @Override5 public void onClick(ClickEvent event) {6 monService.exempleMethode(callback);78 }9 });StockWatcher.javapackage com.google.gwt.sample.stockwatcher.client;import java.util.ArrayList;import java.util.Date;import com.google.gwt.core.client.EntryPoint;import com.google.gwt.event.dom.client.ClickEvent;import com.google.gwt.event.dom.client.ClickHandler;import com.google.gwt.event.dom.client.KeyCodes;import com.google.gwt.event.dom.client.KeyPressEvent;import com.google.gwt.event.dom.client.KeyPressHandler;import com.google.gwt.i18n.client.DateTimeFormat;import com.google.gwt.i18n.client.NumberFormat;import com.google.gwt.user.client.Random;import com.google.gwt.user.client.Timer;import com.google.gwt.user.client.Window;import com.google.gwt.user.client.ui.Button;import com.google.gwt.user.client.ui.FlexTable;import com.google.gwt.user.client.ui.HorizontalPanel;import com.google.gwt.user.client.ui.Label;import com.google.gwt.user.client.ui.RootPanel;import com.google.gwt.user.client.ui.TextBox;import com.google.gwt.user.client.ui.VerticalPanel;public class StockWatcher implements EntryPoint { private VerticalPanel mainPanel = new VerticalPanel(); private FlexTable stocksFlexTable = new FlexTable(); private HorizontalPanel addPanel = new HorizontalPanel(); private TextBox newSymbolTextBox = new TextBox(); private Button addStockButton = new Button("Add"); private Label lastUpdatedLabel = new Label(); private ArrayList<String> stocks = new ArrayList<String>(); private static final int REFRESH_INTERVAL = 5000; // ms
  14. 14. /** * Entry point method. */ public void onModuleLoad() { // Create table for stock data. stocksFlexTable.setText(0, 0, "Symbol"); stocksFlexTable.setText(0, 1, "Price"); stocksFlexTable.setText(0, 2, "Change"); stocksFlexTable.setText(0, 3, "Remove");// Add styles to elements in the stock list table. stocksFlexTable.getRowFormatter().addStyleName(0, "watchListHeader"); stocksFlexTable.addStyleName("watchList"); stocksFlexTable.getCellFormatter().addStyleName(0, 1, "watchListNumericColumn"); stocksFlexTable.getCellFormatter().addStyleName(0, 2, "watchListNumericColumn"); stocksFlexTable.getCellFormatter().addStyleName(0, 3, "watchListRemoveColumn"); // Assemble Add Stock panel. addPanel.add(newSymbolTextBox); addPanel.add(addStockButton); addPanel.addStyleName("addPanel"); // Assemble Main panel. mainPanel.add(stocksFlexTable); mainPanel.add(addPanel); mainPanel.add(lastUpdatedLabel); // Associate the Main panel with the HTML host page. RootPanel.get("stockList").add(mainPanel); // Move cursor focus to the input box. newSymbolTextBox.setFocus(true); // Setup timer to refresh list automatically. Timer refreshTimer = new Timer() { @Override public void run() { refreshWatchList(); } }; refreshTimer.scheduleRepeating(REFRESH_INTERVAL);//Listen for mouse events on the Add button. newSymbolTextBox.addKeyPressHandler(new KeyPressHandler() { public void onKeyPress(KeyPressEvent event) { // if (event.getCharCode() == KeyCodes.KEY_ENTER) { addStock(); // } } });}/** * Add stock to FlexTable. Executed when the user clicks the addStockButton or * presses enter in the newSymbolTextBox. */ private void addStock() { final String symbol = newSymbolTextBox.getText().toUpperCase().trim(); newSymbolTextBox.setFocus(true); // Stock code must be between 1 and 10 chars that are numbers, letters, or dots. if (!symbol.matches("^[0-9A-Z.]{1,10}$")) {
  15. 15. Window.alert("" + symbol + " is not a valid symbol."); newSymbolTextBox.selectAll(); return; } newSymbolTextBox.setText(""); // Dont add the stock if its already in the table. if (stocks.contains(symbol)) return; // Add the stock to the table. int row = stocksFlexTable.getRowCount(); stocks.add(symbol); stocksFlexTable.setText(row, 0, symbol); stocksFlexTable.getCellFormatter().addStyleName(row, 1, "watchListNumericColumn"); stocksFlexTable.getCellFormatter().addStyleName(row, 2, "watchListNumericColumn"); stocksFlexTable.getCellFormatter().addStyleName(row, 3, "watchListRemoveColumn"); // Add a button to remove this stock from the table. Button removeStockButton = new Button("x"); removeStockButton.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { int removedIndex = stocks.indexOf(symbol); stocks.remove(removedIndex); stocksFlexTable.removeRow(removedIndex + 1); } }); stocksFlexTable.setWidget(row, 3, removeStockButton); // Get the stock price. refreshWatchList(); }/** * Update a single row in the stock table. * * @param price Stock data for a single row. */private void updateTable(StockPrice price) { // Make sure the stock is still in the stock table. if (!stocks.contains(price.getSymbol())) { return; } int row = stocks.indexOf(price.getSymbol()) + 1; // Format the data in the Price and Change fields. String priceText = NumberFormat.getFormat("#,##0.00").format( price.getPrice()); NumberFormat changeFormat = NumberFormat.getFormat("+#,##0.00;-#,##0.00"); String changeText = changeFormat.format(price.getChange()); String changePercentText = changeFormat.format(price.getChangePercent()); // Populate the Price and Change fields with new data. stocksFlexTable.setText(row, 1, priceText); stocksFlexTable.setText(row, 2, changeText + " (" + changePercentText + "%)");}private void refreshWatchList() { final double MAX_PRICE = 100.0; // $100.00 final double MAX_PRICE_CHANGE = 0.02; // +/- 2%
  16. 16. StockPrice[] prices = new StockPrice[stocks.size()]; for (int i = 0; i < stocks.size(); i++) { double price = Random.nextDouble() * MAX_PRICE; double change = price * MAX_PRICE_CHANGE * (Random.nextDouble() * 2.0 - 1.0); prices[i] = new StockPrice(stocks.get(i), price, change); } updateTable(prices); } private void updateTable(StockPrice[] prices) { for (int i = 0; i < prices.length; i++) { updateTable(prices[i]); } // Display timestamp showing last refresh. lastUpdatedLabel.setText("Last update : " + DateTimeFormat.getMediumDateTimeFormat().format(new Date())); }}StockWatcher.css/* Formatting specific to the StockWatcher application */body { padding: 10px;}/* stock list header row */.watchListHeader { background-color: #2062B8; color: white; font-style: italic;}/* stock list flex table */.watchList { border: 1px solid silver; padding: 2px; margin-bottom:6px;}/* stock list Price and Change fields */.watchListNumericColumn { text-align: right; width:8em;}/* stock list Remove column */.watchListRemoveColumn { text-align: center;}/* Add Stock panel */.addPanel { margin: 10px 0px 15px 0px;}

×