OverviewWhen developing in GWT, you write Java code that is "compiled" into javascript that will run in the browser. GWT has the concept of classes for client side, server side and those shared between them. It has some limitations over straight java (e.g. lack of reflection and Class.getSimpleName). Our core/domain module and enterprise/gui/coregui modules are gwt compiled. This allows us to write code that utilizes our domain classes right in the browser. We use GWT-RPC to call the server from the browser. These are the *GWTService interfaces and *GwtServiceImpl implementations. We also have to hibernate detach before we can serialize out to the browser. For now we have SerialUtility.prepare to do this though we may try out the gilead project for this. We're not exposing the full remote APIs. A lot of the prototyping has been accomplished with the criteria APIs instead of the specialized calls. I want to prefer the criteria APIs and manually choose the extra set to expose to the GWT client side. This will help us pick a good proper set of APIs for a future more limited and managed remote API. To run the prototype, do a full clean build of the gwt branch and start the server, then go to http://localhost:7080/coregui/CoreGUI.html For development, utilize the "dev-mode" model of GWT development. In this model, you build and start the server as normal, but then separately start a GWT codeserver that will let you do edit-save-refresh development on the client side code. After starting the server, run "mvn gwt:run" or "mvn gwt:debug". The latter will start with jpda so that you can connect intellij or eclipse for debugging sessions on the gwt code. Yes, it let's you step through "browser-side code" in your java debugger. Yes, that is as cool as it sounds. When you run these, it'll start a small UI for dev mode. You can click "Launch Default Browser" to have your browser go to the proper URL for development. This will live "compile" the java gwt code so that you can see your UI. We are using the SmartGWT library to build our UI. This is a GWT module that happens to layered on top of a JavaScript library called SmartClient. It is a rich MVC component library for typical things like tables, forms, etc. Being a client side MVC library, much of our data interaction code happens in the way of subclasses of RPCDataSource. These classes load data for things like tables and forms and can paginate, sort, update, delete, save, etc. in cooperation with the GWT-RPC services. Look at existing examples (e.g. RolesDataSource) for how this is done. SmartGWT is a fairly active project so you can often find good info in the SmartClient.com forums or elsewhere. A very good model for development is inspecting the SmartGWT showcase at http://www.smartclient.com/smartgwt/showcase/ We're using SmartGWT for layout as well as our components. This means the layout is done more like with Swing than as HTML. SmartGWT does layout management and resizing and then sets the DOM elements via absolute positioning. This makes it somewhat more cross-browser compatible, but takes some getting used to if your mostly used to HTML output. It also means that it is often appropriate to have custom components or composite panels start by extending SmartGWT classes like HLayout,VLayout and Canvas. With our components all being GWT classes though we can get a fair amount of reuse and build useful base classes and utilities. As soon as you start to see boiler-plate code think of refactoring. GWT development is not the same as Swing or TCL-TK. We're still running JavaScript in a browser against a DOM. We have to take into account backwards-forwards buttons, bookmarking, session cookies, etc. The biggest of these is the History management. We try to have most of our information pages bookmarkable against a URL. Our GWT app never actually changes the browser "page". Every different view is simply ajax and dhtml manipulation of the DOM. But we also manipulate the browser's url token (the part after the #). That means the url stays: /coregui/CoreGUI.html throughout the app, but you'll see it switch to things like "/coregui/CoreGUI.html#Resources/10001/Monitor/Traits". That sort of path refers to a specific state of the application with certain views displayed. The only views in the app that should not require separate history tokens are things like wizards and modal dialog boxes. This also means that simply rendering a new view in response to a listener is generally the wrong thing to do. (where the right thing to do is fire a history event that will propagate rendering the new views) Gotchas
Miscellaneous Notes
|