GWT12. What’s in it? JRE Emulation (java.lang, java.util) GWT Compiler Hosted Browser Class Library 16. Entry Point Anatomy MyPage.html < script language ="javascript" src =" com.alphacsp.demo.MyModule.nocache.js “/> com.alphacsp.demo.MyModule. <MD5>.cache.js “ 17. Compiled Javascript function com_alphacsp_contacts_Contacts(){var l='',B='" for "gwt:onLoadErrorFn"',z='" for "gwt:onPropertyErrorFn"',wb='"><script>',n='/',kb='226AF0230B73371F6FD432899942EF89.cache.html',ib='6C5371FFFFB5323F9D8058C234E97823.cache.html',jb='86331CB96F6F13236040789304D78367.cache.html',lb='96AB31FA627C259590E8CA143E53C3E0.cache.html',vb='<script id="',sb="<script>com_alphacsp_contacts_Contacts.onInjectionDone('com.alphacsp.contacts.Contacts')<script>",v='=',y='Bad handler "',ob='DOMContentLoaded',mb='E6FAB8BEE24B098AC223BA54C66FD81B.cache.html',xb='SCRIPT',ub='__gwt_marker_com.alphacsp.contacts.Contacts',o='base',q='clear.cache.gif',m='com.alphacsp.contacts.Contacts',u='content',db='gecko',eb='gecko1_8',nb='gwt.hybrid',A='gwt:onLoadErrorFn',w='gwt:onPropertyErrorFn',t='gwt:property',hb='hosted.html?com_alphacsp_contacts_Contacts',bb='ie6',pb='iframe',p='img',qb="javascript:''",r='meta',gb='moduleRequested',ab='msie',s='name',D='opera',rb='position:absolute;width:0;height:0;border:none',F='safari',tb='selectionDone',cb='selectionStart',x='startup',fb='unknown',C='user.agent',E='webkit';var zb=window,k=document,bc=zb.external,yb=zb.__gwtstatsEvent?function(a,b,c,d){zb.__gwtstatsEvent(a,b,c,d)}:null,oc,ec,Eb,Db=l,hc={},rc=[],nc=[],Cb=[],kc,mc;yb&&yb(m,x,cb,{millis:(new Date()).getTime()});if(!zb.__gwt_stylesLoaded){zb.__gwt_stylesLoaded={}}if(!zb.__gwt_scriptsLoaded){zb.__gwt_scriptsLoaded={}}function dc(){try{return bc&&(bc.gwtOnLoad&&zb.location.search.indexOf(nb)==-1)}catch(a){return false}}function gc(){if(oc&&ec){var c=k.getElementById(m);var b=c.contentWindow;b.__gwt_initHandlers=com_alphacsp_contacts_Contacts.__gwt_initHandlers;if(dc()){b.__gwt_getProperty=function(a){return Fb(a)}}com_alphacsp_contacts_Contacts=null;b.gwtOnLoad(kc,m,Db);yb&&yb(m,x,tb,{millis:(new Date()).getTime()})}}function ac(){var j,h=ub,i;k.write(vb+h+wb);i=k.getElementById(h);j=i&&i.previousSibling;while(j&&j.tagName!=xb){j=j.previousSibling}function d(b){var a=b.lastIndexOf(n);return a>=0?b.substring(0,a+1):l};if(j&&j.src){Db=d(j.src)}if(Db==l){var c=k.getElementsByTagName(o);if(c.length>0){Db=c[c.length-1].href}else{var g=k.location;var e=g.href;Db=d(e.substr(0,e.length-g.hash.length))}}else if(Db.match(/^+:/)){}else{var f=k.createElement(p);f.src=Db+q;Db=d(f.src)}if(i){i.parentNode.removeChild(i)}}function lc(){var f=document.getElementsByTagName(r);for(var d=0,g=f.length;d<g;++d){var e=f[d],h=e.getAttribute(s),b;if(h){if(h==t){b=e.getAttribute(u);if(b){var i,c=b.indexOf(v);if(c>=0){h=b.substring(0,c);i=b.substring(c+1)}else{h=b;i=l}hc[h]=i}}else if(h==w){b=e.getAttribute(u);if(b){try{mc=eval(b)}catch(a){alert(y+b+z)}}}else if(h==A){b=e.getAttribute(u);if(b){try{kc=eval(b)}catch(a){alert(y+b+B)}}}}}}function qc(d,e){var a=Cb;for(var b=0,c=d.length-1;b<c;++b){a=a[d[b]]||(a[d[b]]=[])}a[d[c]]=e}function Fb(d){var e=nc[d](),b=rc[d];if(e in b){return e}var a=[];for(var c in b){a[b[c]]=c}if(mc){mc(d,a,e)}throw null}nc[C]=function(){var d=navigator.userAgent.toLowerCase();var b=function(a){return parseInt(a[1])*1000+parseInt(a[2])};if(d.indexOf(D)!=-1){return D}else if(d.indexOf(E)!=-1){return F}else if(d.indexOf(ab)!=-1){var c=/msie ([0-9]+)([0-9]+)/.exec(d);if(c&&c.length==3){if(b(c)>=6000){return bb}}}else if(d.indexOf(db)!=-1){var c=/rv:([0-9]+)([0-9]+)/.exec(d);if(c&&c.length==3){if(b(c)>=1008)return eb}return db}return fb};rc[C]={gecko:0,gecko1_8:1,ie6:2,opera:3,safari:4};com_alphacsp_contacts_Contacts.onInjectionDone=function(){oc=true;yb&&yb(m,x,gb,{millis:(new Date()).getTime()});gc()};com_alphacsp_contacts_Contacts.onScriptLoad=function(){ec=true;gc()};ac();lc();var pc;if(dc()){pc=hb}else{try{qc([D],ib);qc([F],jb);qc([bb],kb);qc([eb],lb);qc([db],mb);pc=Cb[Fb(C)]}catch(a){return}}var jc;function ic(){if(!Eb){Eb=true;gc();if(k.removeEventListener){k.removeEventListener(ob,ic,false)}if(jc){clearInterval(jc)}}}var cc;function fc(){if(!cc){cc=true;var a=k.createElement(pb);a.src=qb;a.id=m;a.style.cssText=rb;a.tabIndex=-1;k.body.appendChild(a);a.src=Db+pc}}if(k.addEventListener){k.addEventListener(ob,function(){fc();ic()},false)}var jc=setInterval(function(){if(/loaded|complete/.test(k.readyState)){fc();ic()}},50);k.write(sb)}com_alphacsp_contacts_Contacts.__gwt_initHandlers=function(i,e,j){var d=window,g=d.onresize,f=d.onbeforeunload,h=d.onunload;d.onresize=function(a){try{i()}finally{g&&g(a)}};d.onbeforeunload=function(a){var c,b;try{c=e()}finally{b=f&&f(a)}if(c!=null){return c}if(b!=null){return b}};d.onunload=function(a){try{j()}finally{h&&h(a)}}};com_alphacsp_contacts_Contacts(); 18. Project structure Resource Description /client Your client-side stuff /server Your server-side stuff /public Your resources (css, images, js) MyModule.gwt.xml Your module configuration 19. Configuration A module file: < module > < inherits name =“ com.google.gwt.user.User “ / > < entry-point class =“ com.alphacsp.demo.MyModule " / > </ module > Contact.gwt.xml 21. Base HTML Template < html > < head > <!-- Properties can be specified to influence deferred binding --> < meta name ='gwt:property' content ='locale=en_UK'> < link rel ="stylesheet" href ="Calendar.css"> < title >Demo Contacts Application</ title > </ head > < body > < script language ="javascript" src =" com.alphacsp.demo.MyModule.nocache.js “/> <!-- Include a history iframe to enable full GWT history support --> < iframe src ="javascript:''" id ="__gwt_historyFrame" style ="width:0;height:0;border:0“/> < div id =“ niceWidgetThingHere ”/> </ body > </ html > Contact.html Standard GWT injection Access and manipulate however you like 22. View Technology (1 of 2) FormPanel loginPanel = new FormPanel (); loginPanel . setFrame ( true ); loginPanel . setBorders ( true ); loginPanel . setButtonAlign ( HorizontalAlignment. CENTER); loginPanel . setHeading (constants. login ()); loginPanel . setFieldWidth (210); loginPanel . setLabelWidth (100); loginPanel . setWidth (400); TextField usernameField = new TextField < String >(); usernameField . setFieldLabel( constants. userNameField ()); loginPanel . add ( usernameField ); TextField passwordField = new TextField < String >(); passwordField . setFieldLabel( constants. passwordField ()); passwordField . setPassword( true ); loginPanel . add ( passwordField ); LoginView.java 23. View Technology (2 of 2) Button loginButton = new Button (constants. loginButton ()); loginButton . setType ("submit"); loginButton . addSelectionListener( new SelectionListener < ButtonEvent >() { @Override public void componentSelected ( ButtonEvent be) { login ( usernameField . getValue (), passwordField . getValue ()); } }); loginPanel . addButton ( loginButton ); LoginView.java Client-side event handling 24. Page Flow private void switchToView ( View view) { viewport . removeAll (); viewport . add (view. getContent ()); viewport . layout (); } Controller.java What’s a page? 25. Form Binding List < TableColumn > columns = new ArrayList < TableColumn >(); columns . add ( new TableColumn ( “name” , constants . nameColumn (), 150)); columns . add ( new TableColumn ( “email” , constants . emailColumn (), 150)); columns . add ( new TableColumn ( “department” , constants . departmentColumn (), 100); Table table = new Table ( new TableColumnModel ( columns )); LookupView.java 26. Pagination // table TableColumnModel columnModel = new TableColumnModel ( columns ); Table table = new Table ( columnModel ); // pagingLoader PagingLoader < PagingLoadConfig > pagingLoader = new BasePagingLoader (proxy); // store ListStore < Employee > store = new ListStore < Employee >( pagingLoader ); // binder new TableBinder < Employee >( table , store ); PagingToolBar toolBar = new PagingToolBar (50); toolBar . bind ( pagingLoader ); LookupView.java 28. Validation emailField . setAllowBlank (false); emailField . setRegex (" [a-zA-Z0-9]@+ "); emailField . getMessages (). setRegexText (“Please use alphabet only); emailField . setValidator ( new Validator () { public String validate ( Field field, String value) { // … } }); LookupView.java 29. AJAX (1 of 2) Registering the service under this name Mandatory stuff… It’s great to be a servlet @RemoteServiceRelativePath ("l ookup ") public interface LoginService extends RemoteService { Employee login ( String userName, String password) throws UnsuccessfulLoginException ; } LoginService.java public interface LoginServiceAsync { void login ( String userName, String password, AsyncCallback<Employee> callback); } LoginServiceAsync.java public class LoginServiceImpl extends RemoteServiceServlet { String login ( String userName, String password) { // …. } } LoginServiceImpl.java 30. AJAX (2 of 2) LoginServiceAsync loginService = GWT . create ( LoginService . class ); loginService . login (username, password, new AsyncCallback<Employee> { public void onSucces s( Employee result) { passwordField . setValue (""); controller . setUsername (username); controller . loggedIn (); } public void onFailure ( Throwable caught) { try { throw caught; } catch ( UnsuccessfulLoginException e) { loginPanel . setHeading (caught. getMessage ()); } catch ( Throwable throwable) { // do whatever } } }); Yeepee! Deal with it… LoginView.java 31. I18N Support (1 of 2) public interface LoginMessages extends Messages { String fieldBlank ( String fieldName); // … } LoginMessages.java fieldBlank = {0} cannot be empty. … . LoginMessages.properties LoginConstants messages = GWT . create ( LoginMessages .class ); String message = messages . fieldBlank (“Username”); anywhere 32. I18N Support (2 of 2) < head > < meta name =" gwt:property " content =" locale=ja_JP "> < head > myPage.html http://www.example.org/myapp.html? locale=fr_CA Locale resolution: By metadata: By request parameter: 33. Error Handling GWT . setUncaughtExceptionHandler ( new GWT . UncaughtExceptionHandler () { public void onUncaughtException ( Throwable e) { GWT . log (e. getMessage (), e); // … } }); Contacts.java