Secrets of the GWT

  • 11,124 views
Uploaded on

Overview of GWT and new features in 2.1

Overview of GWT and new features in 2.1

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

Views

Total Views
11,124
On Slideshare
0
From Embeds
0
Number of Embeds
5

Actions

Shares
Downloads
0
Comments
2
Likes
13

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
  • \n
  • What’s new in GWT?\n
  • \n
  • \n
  • Google Web Toolkit 101\n
  • \n
  • \n
  • \n
  • You get the benefit of code completion, javadoc\nAND Eclipse refactoring tools\n
  • One GWT\n
  • \n
  • \n
  • \n
  • \n
  • GWT has two main goals\n
  • Google Web Toolkit gives you tools for the whole development lifecycle\n
  • Easiest way to get started is with Google Plugin for Eclipse\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Instantiations, free, contribute WindowBuilder\nGenerates corresponding Java code and provides round-trip editing\nUiBinder, externalize strings, absolute layout, new LayoutPanel\n
  • You can also use GWT Designer with UiBinder XML templates\n
  • GWT Designer provides a nice CSS editor with visual preview\n
  • Now you’ve written some code and you want to test it.\nGWT development mode lets you test changes quickly without having to compile to JavaScript\n
  • Now you’ve written some code and you want to test it.\nGWT development mode lets you test changes quickly without having to compile to JavaScript\n
  • Now you’ve written some code and you want to test it.\nGWT development mode lets you test changes quickly without having to compile to JavaScript\n
  • Browser plugin connects to the GWT code server running in Eclipse\nand runs your Java code.\n
  • Browser plugin connects to the GWT code server running in Eclipse\nand runs your Java code.\n
  • Browser plugin connects to the GWT code server running in Eclipse\nand runs your Java code.\n
  • Browser plugin connects to the GWT code server running in Eclipse\nand runs your Java code.\n
  • Browser plugin connects to the GWT code server running in Eclipse\nand runs your Java code.\n
  • Dev mode also lets you debug right inside Eclipse\n
  • When you’re ready to deploy, you run the GWT compiler, which\npackages your app in a standard WAR structure\n
  • Download SpeedTracer for Chrome from the GWT team\n
  • Launch from Eclipse to find Java code for certain events\n
  • SpeedTracer can even show server-side speed traces in GAE\nand Spring tcServer\n
  • Deploy WAR to any servlet container\nOr one click to GAE\n
  • \n
  • How do you upgrade your application?\nEnsure that new images, CSS, etc. are updated on each browser?\nGenerates random URLs\nNocache does deferred binding (browser detection, i18n), then pulls in cached permutation for the browser\n
  • GWT compiler creates the bundled image and calculates cropping\nso your can use each image just like normal\n
  • GWT compiler creates the bundled image and calculates cropping\nso your can use each image just like normal\n
  • GWT compiler creates the bundled image and calculates cropping\nso your can use each image just like normal\n
  • GWT compiler creates the bundled image and calculates cropping\nso your can use each image just like normal\n
  • \n
  • \n
  • \n
  • Even more on its way: lightweight collections, enum ordinalization\n\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • DatastoreObject ID/version, Key, enum, value type\n
  • \n
  • ListItem a POJO on server only\nAll proxies go in a shared directory (client and server)\n
  • interface extends RequestFactory, @Service points to impl, locator can find it\nservice stubs extend RequestContext, return parameterized Request\naccessor for each service stub\n
  • Create a new object, call .create() to get mutable obj\nFire the request with Receiver (like AsyncCallback)\n
  • To update, must edit first to get mutable obj\n
  • .with\n
  • must edit() parent obj, init Collections, save .with() for relations & value types\n
  • No special methods to implement\nReusable via factory\n
  • No special methods to implement\nReusable via factory\n
  • \n
  • evil back button\n
  • \n
  • Extends Place, constructors can take arguments\nTokenizer converts to/from String\n
  • \n
  • Lists all places that participate in browser history\nAll generated, can also implement PlaceHistoryMapper yourself\n
  • \n
  • instantiate ActivityManagers, PlaceHistoryMapper, PlaceHistoryHandler\nAdd a widget to the root panel and handleCurrentHistory()\nSee also CachingActivityManager, FilteredActivityManager\n
  • Define a model to cleanly separate view & presenter code\n
  • Column represents model of a column, contains no widget code\nSo can use in presenter or view\n
  • \n
  • \n
  • \n
  • Java is the kingdom of nouns\n
  • \n
  • How do you shrink it and make compile faster? shows each permutation, split point, package\n
  • \n
  • \n

Transcript

  • 1. Secrets of the GWTDavid ChandlerGoogle Web Toolkit TeamAtlanta, GA USAdrfibonacci@google.com
  • 2. Agenda Why rich Web apps with GWT? GWT Quickstart Developer tools GWT performance for your users Building with GWT 2.1
  • 3. GWT in 10 sec Asynchronous JavaScript And XML++
  • 4. GWT in 60 sec Open source Java to JavaScript compiler Lets you write rich Web apps in Java Cross-browser just works (FireFox, Chrome, Safari, IE 6+) Produces small, fast JavaScript Easy (and efficient) RPC Great for large projects / teams
  • 5. Browser-Proof Your JS Code IE Firefo x i Safar e m Chro Opera 5
  • 6. No plugins required Silverlight VML Flash 6
  • 7. Can you find the bug? 7
  • 8. Can you find the bug? Hint: JavaScript is a dynamic language 7
  • 9. Catch errors at compile time Java is a static language 8
  • 10. Completion, refactoring... 9
  • 11. Eating our own dogfood += AdSense, Maps, Docs, Groups... 10
  • 12. Rich ecosystemwww.gwtmarketplace.com
  • 13. More ecosystem Util: gwt-dnd, gwt-log, gwt-voices, gwt-fx Mobile: gwt-mobile-toolkit
  • 14. 4+ years in review May 2006 GWT 1.0 Launch at JavaOne … … Aug 2008 GWT 1.5 Java 5 language support Apr 2009 GWT 1.7 Dedicated IE8 supportFall 2009 GWT 2.0 UIBinder (XML template), runAsync() Oct 2010 GWT 2.1 MVP, RequestFactory, Spring Roo 13
  • 15. GWT Quickstart> svn checkout https://google-web-toolkit.googlecode.com/svn/trunk/samples/expenses expenses> cd expenses/src/main/webapp> mvn -f ../../../pom.xml gwt:run (dev mode)(note: most projects can use mvn gwt:run in the dir containing pom.xml--thisone is special because it loads test data from a .txt file in src/main/webapp)1.Browse to http://127.0.0.1:8888/LoadExpensesDB.html?gwt.codesvr=127.0.0.1:99972.Click Generate Data button3.Browse to Expenses.html to run the appTo create an Eclipse project:1.Install Sonatype m2eclipse and m2extras2.File | Import | Existing maven project, select expenses/pom.xml
  • 16. GWT delivers... Productivity for developers - Language, IDEs, tools, libraries - People, ecosystem Performance for users - Perfect caching - Whole program optimization 15
  • 17. Developing with GWT Develop - Google Plugin for Eclipse, GWT Designer, STS / Roo Debug - In Eclipse with dev mode browser plugin Optimize - SpeedTracer for GWT, App Engine, Spring Insight Deploy - Standard WAR or one-button push to App Engine
  • 18. Google Plugin for Eclipse
  • 19. Google Plugin for Eclipse
  • 20. Google Plugin for Eclipse Easiest way to get latest GWT, GAE SDKs
  • 21. Google Plugin for Eclipse Easiest way to get latest GWT, GAE SDKs Debug / Run / Optimize / Deploy
  • 22. Google Plugin for Eclipse Easiest way to get latest GWT, GAE SDKs Debug / Run / Optimize / Deploy Wizards (new module, entry point, ClientBundle, UiBinder)
  • 23. Google Plugin for Eclipse Easiest way to get latest GWT, GAE SDKs Debug / Run / Optimize / Deploy Wizards (new module, entry point, ClientBundle, UiBinder) Quick fixes (auto-create RPC Async interface)
  • 24. Google Plugin for Eclipse Easiest way to get latest GWT, GAE SDKs Debug / Run / Optimize / Deploy Wizards (new module, entry point, ClientBundle, UiBinder) Quick fixes (auto-create RPC Async interface) Run As | GWT JUnit Test
  • 25. Google Plugin for Eclipse Easiest way to get latest GWT, GAE SDKs Debug / Run / Optimize / Deploy Wizards (new module, entry point, ClientBundle, UiBinder) Quick fixes (auto-create RPC Async interface) Run As | GWT JUnit Test Maven integration via m2eclipse plugin
  • 26. GWT Designer Java, ui.xml
  • 27. GWT Designer & UiBinder
  • 28. GWT Designer CSS Editor
  • 29. Development cycle 22
  • 30. Development cycle Write Code 22
  • 31. Development cycle Write Hit Code Refresh 22
  • 32. Development cycle Write Hit Code Refresh Quick Test 22
  • 33. How dev mode works A real browser 23
  • 34. How dev mode works A real browser 23
  • 35. How dev mode works A real browser Java Virtual Machine Duke, the Java mascot Copyright © Sun Microsystems Inc., all rights reserved. 23
  • 36. How dev mode works A real browser Web Server Java Virtual Machine Duke, the Java mascot Copyright © Sun Microsystems Inc., all rights reserved. 23
  • 37. How dev mode works A real browser Web Server Code Server Java Virtual Machine Duke, the Java mascot Copyright © Sun Microsystems Inc., all rights reserved. 23
  • 38. How dev mode works A real browser Web Server Code Server Java Virtual Machine Duke, the Java mascot Copyright © Sun Microsystems Inc., all rights reserved. 23
  • 39. Debug in dev mode 24
  • 40. Compile for Production Source files: Code, CSS, Images, Resources, … GWT Compiler Your app running here. No plugins. 25
  • 41. Optimize with Speed Tracer
  • 42. Launch SpeedTracerFrom Chrome...Or from Eclipse...
  • 43. Server traces GAE, tcServer
  • 44. One click deploy to GAE
  • 45. Performance for your users Latency • Perfect Caching Number of connections • ClientBundle Bandwidth • data: URLs & MHTML packaging Browser Performance • Developer guided code splitting • Compiler optimizations 30
  • 46. Perfect caching } index.html … ………… ………… ………… … … ………  ……………… … … … … … HTTP … …… <script src=foo.nocache.js … > ………… If-Modifed-Since foo.nocache.js } ……… … ………… ………  … …… A83B1C.cache.html … … A83B1C.cache.html … … ………   ………… … … ……… …………… … …………… ……  … … ……     …  …… … …… … … ……… ………… …… FOREVER …… ……… … …… …… … … …… … F7312.cache.txt … … 6C5BA.cache.png  …… ……  …… …  ………… … …… Cacheable … …   ……… ……… ……… … ……… … …… … …………… ………… ……… ……… … …………   ………………… …… … … … …… … …… 6C5BA.cache.png F7312.cache.txt 31
  • 47. Image sprites for free 32
  • 48. Image sprites for free 11 separate images 32
  • 49. Image sprites for free 11 separate images 1 bundled image 32
  • 50. Image sprites for free 20,558 bytes 11 separate images 6,824 bytes 1 bundled image ∑ Separate Bundled 32
  • 51. Without ClientBundle 33
  • 52. Deferred binding Firefox Webkit (Safari) Opera IE Typical portable 2876 ms 1276 ms 2053 ms 4078 ms setInnerText() textContent=... - 908 ms 1386 ms - innerText=... 2477 ms 918 ms 1520 ms 2469 ms DOM manipulation 7148 ms 1997 ms 4836 ms 14800 ms 34
  • 53. Deferred binding Firefox Webkit (Safari) Opera IE Typical portable 2876 ms 1276 ms 2053 ms 4078 ms setInnerText() textContent=... - 908 ms 1386 ms - innerText=... 2477 ms 918 ms 1520 ms 2469 ms DOM manipulation 7148 ms 1997 ms 4836 ms 14800 ms Improvement 14% 29% 32% 39% 34
  • 54. GWT compiler optimization“The fastest code is that which does not run.” Joel Webber GWT co-creator
  • 55. GWT compiler optimization Does all the stuff you’d do by hand in a tight JS app - Shrinking (obfuscation) - Modularization (pay only for what you use) - Dead code removal - Method inlining …but automated and even tighter Developer-guided code splitting (runAsync)
  • 56. What’s new in GWT 2.1?
  • 57. What’s new in GWT 2.1? Integration with Spring / Roo
  • 58. What’s new in GWT 2.1? Integration with Spring / Roo SafeHTML wrappers
  • 59. What’s new in GWT 2.1? Integration with Spring / Roo SafeHTML wrappers Better Maven support in GPE
  • 60. What’s new in GWT 2.1? Integration with Spring / Roo SafeHTML wrappers Better Maven support in GPE RequestFactory
  • 61. What’s new in GWT 2.1? Integration with Spring / Roo SafeHTML wrappers Better Maven support in GPE RequestFactory Activities and Places
  • 62. What’s new in GWT 2.1? Integration with Spring / Roo SafeHTML wrappers Better Maven support in GPE RequestFactory Activities and Places Cell Widgets and Editor framework
  • 63. What’s new in GWT 2.1? Integration with Spring / Roo SafeHTML wrappers Better Maven support in GPE RequestFactory Activities and Places Cell Widgets and Editor framework Built-in logging
  • 64. Four flavors of RPC
  • 65. Four flavors of RPC1. RequestBuilder + JSONParser (see RESTY-GWT)
  • 66. Four flavors of RPC1. RequestBuilder + JSONParser (see RESTY-GWT)2. RequestBuilder + XMLParser
  • 67. Four flavors of RPC1. RequestBuilder + JSONParser (see RESTY-GWT)2. RequestBuilder + XMLParser3. GWT-RPC (easiest)
  • 68. Four flavors of RPC1. RequestBuilder + JSONParser (see RESTY-GWT)2. RequestBuilder + XMLParser3. GWT-RPC (easiest)4. RequestFactory (new in 2.1)
  • 69. GWT-RPC@RemoteServiceRelativePath("greet")public interface GreetingService extends RemoteService { String greetServer(String name) throws IllegalArgumentException;}public interface GreetingServiceAsync { void greetServer(String input, AsyncCallback<String> callback) throws IllegalArgumentException;}public class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService{ public String greetServer(String input) throws IllegalArgumentException { ... }}
  • 70. Simple, powerful GWT-RPC Send / receive Plain Old Java Objects (POJO) - Easy: interface, async, & implementation - Versioned to help keep client & server in sync - Even smaller than JSON - Supports polymorphism - No JavaScript hijacking risk (JSON attack) - Easy to find all calls to given service in IDE
  • 71. GWT 2.1 RequestFactory Newer alternative to GWT-RPC Designed for data-oriented services - Higher level of abstraction than GWT-RPC - Foundation for future caching / batching Even faster than GWT-RPC - JSON-based == very fast (no serialization / deserialization required) - Tracks changes on the client and sends only diffs
  • 72. RequestFactory The entity / DTO problem EntityProxy / ValueProxy Service stub interfaces extend RequestContext AppRequestFactory extends RequestFactory GWT.create(MyAppRequestFactory.class)
  • 73. EntityProxy@Entitypublic class ItemList extends DatastoreObject{ private String name; private Key<AppUser> owner; private ListType listType; @Embedded private List<ListItem> items; // value type ...}@ProxyFor(ItemList.class)public interface ItemListProxy extends DatastoreObjectProxy{ // TODO enums work! public enum ListType {NOTES, TODO} String getName(); void setName(String name); List<ListItemProxy> getItems(); AppUserProxy getOwner(); // NOT Key ...}
  • 74. DatastoreObjectpackage com.listwidget.domain;public class DatastoreObject{ @Id private Long id; private Integer version = 0; @PrePersist void onPersist() { this.version++; } ...}package com.listwidget.shared.proxy;public interface DatastoreObjectProxy extends EntityProxy{ Long getId(); Integer getVersion();}
  • 75. ValueProxypublic class ListItem // POJO{ private String itemText; private Date dateCreated; public Date getDateCreated() { return dateCreated; }}@ProxyFor(value = ListItem.class)public interface ListItemProxy extends ValueProxy{ String getItemText(); void setItemText(String itemText); Date getDateCreated();}
  • 76. Making a RequestFactorypublic interface ListwidgetRequestFactory extends RequestFactory{ @Service(value = ItemListDao.class, locator = DaoServiceLocator.class) interface ItemListRequestContext extends RequestContext { Request<List<ItemListProxy>> listAll(); Request<Void> save(ItemListProxy list); Request<ItemListProxy> saveAndReturn(ItemListProxy newList); } ItemListRequestContext itemListRequest();}private final ListwidgetRequestFactory rf = GWT.create(ListwidgetRequestFactory.class);
  • 77. Using RequestFactory @Override public void persistList(String listName) { final ListwidgetRequestFactory rf = this.clientFactory .getRequestFactory(); ItemListRequestContext reqCtx = rf.itemListRequest(); final ItemListProxy newList = reqCtx.create(ItemListProxy.class); newList.setName(listName); newList.setListType(ListType.TODO); reqCtx.saveAndReturn(newList).fire(new Receiver<ItemListProxy>() { @Override public void onSuccess(final ItemListProxy savedList) { // Refresh table listDataProvider.getData(); } }); }
  • 78. Using RequestFactory @Override public void update(int index, ItemListProxy obj, final String newName) { ItemListRequestContext reqCtx = clientFactory.getRequestFactory() .itemListRequest(); ItemListProxy editable = reqCtx.edit(obj); editable.setName(newName); reqCtx.save(editable).fire(new Receiver<Void>() { @Override public void onSuccess(Void response) { eventBus.fireEvent(new MessageEvent(newName + " updated", MessageType.INFO)); } }); }
  • 79. Using RequestFactory private void getData() { // To retrieve relations and value types, use .with() Request<List<ItemListProxy>> findAllReq = rf.itemListRequest() .listAll().with("owner"); // Receiver specifies return type findAllReq.fire(new Receiver<List<ItemListProxy>>() { @Override Text public void onSuccess(List<ItemListProxy> response) { updateRowData(0, response); } }); }
  • 80. Using RequestFactory editList = reqCtx.edit(editList); List<ListItemProxy> items = editList.getItems(); // must initialize collections if (items == null) { editList.setItems(new ArrayList<ListItemProxy>()); } editList.getItems().add(newItem); reqCtx.save(editList).with("items").to(new Receiver<Void>() { @Override public void onSuccess(Void response) { itemsProvider.setList(editList.getItems()); itemsProvider.refresh(); } }).fire();
  • 81. GWT MVP - Concepts
  • 82. GWT MVP - Concepts View - Interface + implementation - Interface enables testing without GWTTestCase - Typically expensive to construct so make reusable
  • 83. GWT MVP - Concepts View - Interface + implementation - Interface enables testing without GWTTestCase - Typically expensive to construct so make reusable Presenter - No Widgets, just business logic - Middle man between service layer and views
  • 84. GWT MVP - Concepts Activities - Similar to presenters, but higher level - Automatically warn users before leaving - Instantiate view (or obtain from factory) - Mapped from Places
  • 85. GWT MVP - Concepts Places - Place represents bookmarkable state of an activity - PlaceController makes back button / bookmarks work like users expect - PlaceTokenizers map to / from String tokens on URL
  • 86. Activitypublic class EditListActivity extends AbstractActivity implements Presenter{ private ClientFactory clientFactory; private EventBus eventBus; public EditListActivity(ClientFactory cf, EditListPlace editListPlace) { this.clientFactory = cf; this.itemListToken = editListPlace.getToken(); } @Override public void start(final AcceptsOneWidget panel, EventBus eventBus) { this.eventBus = eventBus; ... panel.setWidget(clientFactory.getEditListView()); } ...}
  • 87. Placepublic class EditListPlace extends Place{ private String token; public EditListPlace(String token) { this.token = token; } public String getToken() { return token; } public static class Tokenizer implements PlaceTokenizer<EditListPlace> { public EditListPlace getPlace(String token) { return new EditListPlace(token); } public String getToken(EditListPlace place) { return place.getToken(); } }}
  • 88. ActivityMapperpublic class AppActivityMapper implements ActivityMapper { private ClientFactory clientFactory; public AppActivityMapper(ClientFactory clientFactory) { super(); this.clientFactory = clientFactory; } @Override public Activity getActivity(Place place) { if (place instanceof EditListPlace) { return new EditListActivity(clientFactory, (EditListPlace) place); } if (place instanceof ListsPlace) { return new ListsActivity(clientFactory); } return null; }}
  • 89. PlaceHistoryMapper/** * PlaceHistoryMapper interface is used to attach all places which the * PlaceHistoryHandler should be aware of. This is done via the @WithTokenizers * annotation or by extending PlaceHistoryMapperWithFactory and creating a * separate TokenizerFactory. */@WithTokenizers({ ListsPlace.Tokenizer.class, EditListPlace.Tokenizer.class })public interface AppPlaceHistoryMapper extends PlaceHistoryMapper{}
  • 90. How it works ValueChangeEvent PlaceHistoryHandler maps token prefix to Place PlaceTokenizer<Place> obtained from PlaceHistoryMapper ActivityManager ActivityManager ActivityMapper ActivityMapper Activity. Activity. start() start()
  • 91. Activities and Places wiring// Start ActivityManager for the nav (west) panel with our WestActivityMapperActivityMapper westActivityMapper = new WestActivityMapper(clientFactory);ActivityManager westActivityManager = new ActivityManager(westActivityMapper, eventBus);westActivityManager.setDisplay(westPanel);// Start ActivityManager for the main (center) panel with our CenterActivityMapperActivityMapper centerActivityMapper = new CenterActivityMapper(clientFactory);ActivityManager centerActivityManager = new ActivityManager(centerActivityMapper, eventBus);centerActivityManager.setDisplay(centerPanel);// Start PlaceHistoryHandler with our PlaceHistoryMapperPlaceHistoryMapper historyMapper = GWT.create(AppPlaceHistoryMapper.class);PlaceHistoryHandler historyHandler = new PlaceHistoryHandler(historyMapper);historyHandler.register(placeController, eventBus, defaultPlace);RootPanel.get().add(dockLayoutPanel);// Goes to place represented on URL or default placehistoryHandler.handleCurrentHistory();
  • 92. Cell Widgets Fast, lightweight table rendering Data binding with DataProviders, ValueUpdaters Scrolling and paging controls TextBox, IntegerBox, ValueBox<T> - Can now create custom Parser<T> & Renderer<T>
  • 93. Cell Widgets
  • 94. Editable Column// Editable column for list namenameColumn = new Column<ItemListProxy,String>(new EditTextCell()){ @Override public String getValue(ItemListProxy list) { return list.getName(); }};
  • 95. Custom Column type// Note Flyweight pattern: only one instance of HyperlinkCell passed to the ColumnColumn<ItemListProxy, Hyperlink> linkColumn = new Column<ItemListProxy, Hyperlink>(new HyperlinkCell()){ @Override public Hyperlink getValue(ItemListProxy list) { String proxyToken = clientFactory.getRequestFactory().getHistoryToken(list.stableId()); String historyToken = clientFactory.getHistoryMapper().getToken(new EditListPlace(proxyToken)); Hyperlink h = new Hyperlink(list.getName(),historyToken); return h; }};
  • 96. Populating a CellTablepublic static class MyDataProvider extends AsyncDataProvider<ItemListProxy>{ @Override protected void onRangeChanged(HasData<ItemListProxy> display) { // To retrieve relations and value types, use .with() Request<List<ItemListProxy>> findAllReq = rf.itemListRequest() .listAll().with("owner"); // Receiver specifies return type findAllReq.fire(new Receiver<List<ItemListProxy>>() { @Override public void onSuccess(List<ItemListProxy> response) { updateRowData(0, response); } }); }}this.myDataProvider = new MyDataProvider(requestFactory);
  • 97. Updating with a CellTablepublic class NameFieldUpdater implements FieldUpdater<ItemListProxy, String>{ @Override public void update(int index, ItemListProxy obj, final String newName) { ItemListRequestContext reqCtx = clientFactory.getRequestFactory() .itemListRequest(); ItemListProxy editable = reqCtx.edit(obj); editable.setName(newName); reqCtx.save(editable).fire(new Receiver<Void>() { @Override public void onSuccess(Void response) { eventBus.fireEvent(new MessageEvent(newName + " updated", MessageType.INFO)); } }); }};// Make list name field editabledisplay.getNameColumn().setFieldUpdater(new NameFieldUpdater());
  • 98. GWT Logging GWT now has java.util.Logging emulation Configure in your .gwt.xml Easily enable remote logging, too
  • 99. GWT secrets-compileReport
  • 100. GWT secrets Speed up compilation on large projects - -draftCompile skips optimizations - Set only one user-agent in gwt.xml for dev See GWT FAQ for more tips
  • 101. Thank you! Where to get it: http://code.google.com/webtoolkit/ Wiki, issue tracker, source: http://code.google.com/p/google-web-toolkit/ Official GWT blog: http://google-web-toolkit.blogspot.com/ Twitter: http://twitter.com/#!/googledevtools 69