Google Web Toolkit Progetto di Applicazioni Software a.a. 2011/12 Massimo Mecella
Introduction Ajax (Asynchronous JavaScript and XML) refers to a broad range of techniques Beyond the technical jargon, Ajax represents an architecture for the software that is designed to be used with any web browser, but that includes an interface with the responsive feel of a desktop application
Introduction For example, a grid component such as a spreadsheet that appears in the web page responds instantly to the user's manipulation of the data, without the time delays or visual disruptions caused by the page "refreshing" or being rebuilt with new HTTP requests. Google's Gmail and Calendar, and Yahoo! Maps, are three examples of typical Ajax applications
AJAX in a nutshell Ajax works by communicating with the application's middle and/or database tiers using a client-side JavaScript object. This object is called XMLHttpRequest (XHR) The web page is composed of and programmed with common, standard technologies namely, HTML/XHTML, cascading style sheets (CSS), JavaScript, and the Document Object Model API that lies behind each web page's structure
AJAX in a nutshell The data that the page exchanges with its server tiers, such as a product database, can be plain text, XML, or a format called JavaScript Object Notation (JSON) For example, the user might choose a product name from a selection list widget on a web page. In response to this event, the application uses XHR to send a request for data on this product
AJAX in a nutshell The page never changes, because the application sent the request asynchronously behind the scenes. The server component, such as a PHP file or a servlet, receives the HTTP request, then sends back a response containing information about the product, in, say, XML or JSON format. The application processes the request using JavaScript's DOM API, or by converting the JSON value to a client-side object. The user sees the new information on the web page, hopefully without a very long delay
How to program in AJAX? A developer will typically create his Ajax application by writing XHTML pages and JavaScript code with his favorite integrated development environment (IDE) or even text editors. A number of different libraries and frameworks exist (cf. http://en.wikipedia.org/wiki/ List_of_Ajax_frameworks for a list) Dojo toolkit Prototype Yahoo! User Interface library script.aculo.us. They are designed for developers who are already fairly well advanced in their JavaScript knowledge
GWT The GWT takes a different approach to Ajax Using the GWT framework, you can design and program your user interface using only the Java language. You can use the GWT's command-line tools to check the syntax of the Java classes, then automatically generate the JavaScript for the application's client-side The design of the user interface is very similar to using Java's Swing API
GWT You can thus view the GWT as a JavaScript-generation tool for Java programmers, as well as a framework for creating redistributable or extensible user-interface widgets You do not have to know a lick of JavaScript, although you can include raw JavaScript in your code using special programming constructs that the GWT provides
My First GWT application Reference: https://developers. google.com/webtoolkit/doc/latest/tut orial/gettingstarted
My First GWT application 1. Set-up the development environment (Eclipse if you like the GWT plugin) and/or command-line tools webappcreator creates all the needed files and directories needed for the application
My First GWT application 2. Create a new project directories /src/com/google/gwt/sample/stockwatcher - Contains the GWT module definition and initial application files /test/com/google/gwt/sample/stockwatcher - Contains JUnit test directory and a starter test class /war - Contains static resources that can be served publicly, such as image files, style sheets, and HTML host pages /war/web-inf - Contains Java web application files /war/web-inf/lib - Contains Java web application libraries
My First GWT application files StockWatcher.gwt.xml - GWT module definition StockWatcher.html - host page StockWatcher.css - application style sheet web.xml - Java web application descriptor The code for a web application executes within an HTML document. In GWT, we call this the host page. The host page references the application style sheet StockWatcher.java - GWT entry point class GreetingService.java, GreetingServiceAsync.java, GreetingServiceImpl.java GWT sample RPC classes gwt-servlet.jar - GWT server runtime library StockWatcherTest.java - Starter test case for StockWatcher The entry point class implements the GWT interface EntryPoint. It contains the method onmoduleload
My First GWT application 3. Code your application Selection of the needed widgets see https://developers.google.com/webtoolkit/doc/latest/refwidgetgallery In our example...
My First GWT application Choose the panel structure (analogously to Java Swing)
My First GWT application Define event handling
G:\Massimo\Didattica\2011_2012\ProgettoApplicazioniSoftware\Slides\8 Code_StockWatcher.html giovedì 12 aprile 2012 12:29 <!doctype html> <!-- The DOCTYPE declaration above will set the --> <!-- browser's rendering engine into --> <!-- "Standards Mode". Replacing this declaration --> <!-- with a "Quirks Mode" doctype is not supported. --> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <link type="text/css" rel="stylesheet" href="stockwatcher.css"> <title>stockwatcher</title> <script type="text/javascript" language="javascript" src= "stockwatcher/stockwatcher.nocache.js"></script> </head> <body> <h1>stockwatcher</h1> <div id="stocklist"></div> <iframe src="javascript:''" id=" gwt_historyframe" tabindex='-1' style= "position:absolute;width:0;height:0;border:0"></iframe> <noscript> <div style="width: 22em; position: absolute; left: 50%; margin-left: -11em; color: red; background-color: white; border: 1px solid red; padding: 4px; font-family: sans-serif"> Your web browser must have JavaScript enabled in order for this application to display correctly. </div> </noscript> </body> </html> -1-
G:\Massimo\Didattica\2011_2012\ProgettoApplicazioniSoftware\Slides\8 Code_StockPrice.java giovedì 12 aprile 2012 12:28 package com.google.gwt.sample.stockwatcher.client; public class StockPrice { private String symbol; private double price; private double change; public StockPrice() { public StockPrice(String symbol, double price, double change) { this.symbol = symbol; this.price = price; this.change = change; public String getsymbol() { return this.symbol; public double getprice() { return this.price; public double getchange() { return this.change; public double getchangepercent() { return 100.0 * this.change / this.price; public void setsymbol(string symbol) { this.symbol = symbol; public void setprice(double price) { this.price = price; public void setchange(double change) { this.change = change; -1-
G:\Massimo\Didattica\2011_2012\ProgettoApplicazioniSoftware\Slides\8 Code_StockWatcher.java giovedì 12 aprile 2012 12:29 package com.google.gwt.sample.stockwatcher.client; import com.google.gwt.core.client.entrypoint; 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; 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.user.client.window; import java.util.arraylist; import com.google.gwt.user.client.timer; import com.google.gwt.user.client.random; import com.google.gwt.i18n.client.numberformat; import com.google.gwt.i18n.client.datetimeformat; import java.util.date; /** * Entry point classes define <code>onmoduleload()</code>. */ public class StockWatcher implements EntryPoint { private static final int REFRESH_INTERVAL = 5000; // ms 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>(); /** * 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"); // Assemble Add Stock panel. addpanel.add(newsymboltextbox); addpanel.add(addstockbutton); // Assemble Main panel. mainpanel.add(stocksflextable); mainpanel.add(addpanel); mainpanel.add(lastupdatedlabel); -1-
G:\Massimo\Didattica\2011_2012\ProgettoApplicazioniSoftware\Slides\8 Code_StockWatcher.java giovedì 12 aprile 2012 12:29 // 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. addstockbutton.addclickhandler(new ClickHandler() { public void onclick(clickevent event) { addstock(); ); // Listen for keyboard events in the input box. newsymboltextbox.addkeypresshandler(new KeyPressHandler() { public void onkeypress(keypressevent event) { if (event.getcharcode() == KeyCodes.KEY_ENTER) { addstock(); ); 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$")) { Window.alert("'" + symbol + "' is not a valid symbol."); newsymboltextbox.selectall(); return; newsymboltextbox.settext(""); // Don't add the stock if it's 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); // Add a button to remove this stock from the table. -2-
G:\Massimo\Didattica\2011_2012\ProgettoApplicazioniSoftware\Slides\8 Code_StockWatcher.java giovedì 12 aprile 2012 12:29 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(); /** * Generate random stock prices. */ private void refreshwatchlist() { final double MAX_PRICE = 100.0; // $100.00 final double MAX_PRICE_CHANGE = 0.02; // +/- 2% 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); /** * Update the Price and Change fields all the rows in the stock table. * * @param prices * Stock data for all rows. */ 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())); /** * Update a single row in the stock table. * * @param price * Stock data for a single row. */ -3-
G:\Massimo\Didattica\2011_2012\ProgettoApplicazioniSoftware\Slides\8 Code_StockWatcher.java giovedì 12 aprile 2012 12:29 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 + "%)"); -4-