Top Ten Reasons to use Google Plugin for Eclipse

Posted by David Chandler - Tuesday, March 29, 2011 at 12:09:00 PM

As I speak at JUGs and conferences around the world, I'm often surprised that some folks have never seen some of the best features of Google Plugin for Eclipse, such as using the Eclipse debugger with a GWT app. So in no particular order, here are 10 reasons you should use Google Plugin for Eclipse (GPE).

  1. GWT+GAE made easy. GPE is the easiest way to get started with GWT and Google App Engine (GAE). Just check the SDKs box when you install the plugin through the Eclipse update site. It's easy to upgrade the SDKs this way (Help | Check for updates), and a status bar message in Eclipse will remind you when new versions are available.
  2. Wizards. It's easy to create your first GWT+GAE project. Click File | New | Web application project and you'll get a sample app that you can run locally to kick the tires and then deploy to Google App Engine. Beyond creating a new project, there are wizards to create new UiBinder templates, ClientBundles, GWT modules, and entry points. To use the wizards, click File | New and look for the items with the GWT toolbox logo (or click File | New | Other... and browse to the Google Web Toolkit folder).
  3. GWT Designer, now bundled with GPE, lets you quickly create a GUI. To see it in action, create a class that extends GWT's Composite class, then right-click on the file and Open With | GWT Designer. When the editor opens, click on the Design tab at the bottom. After GWT Designer launches, click a tool on the palette (say, LayoutPanel), then click on the empty design window to drop the widget in place. Click the source tab to see the code that GWT Designer wrote for you. It's a great way to learn the new cell widgets like CellTable and TextColumn, and GWT Designer has a built-in WYSIWYG CSS editor, too.
  4. Quick fixes and warnings help you write good GWT code quickly. For example, when you create an interface that extends GWT's RemoteService class, GPE will prompt you to create the corresponding async interface required for GWT-RPC. Just click Ctrl+1 (Quick Fix) on the red squiggly and away you go.
  5. Dev mode integration lets you test your code quickly. Run As | Web Application starts GWT development mode and the App Engine dev server (if applicable) so you can test your code in the browser. When dev mode starts, look for the Development Mode tab in Eclipse and double-click the URL to launch your app in the default browser. With GWT dev mode running, you can make changes to your Java code, hit Refresh in the browser, and see your changes live.
  6. Debugging in dev mode rocks. Set a breakpoint in Eclipse, right-click on your project, and Debug As | Web Application. Switch to the browser and run your code. Eclipse will open the Debug perspective where you can step through your code line-by-line, inspect variables, etc.
  7. One-click deploy to Google App Engine. Just click the Google App Engine logo on the toolbar.
  8. Maven support. GPE works with Maven projects via m2eclipse (see setup instructions). Check out a Maven project like the Expenses GWT+GAE sample app into your workspace, then click File | Import | Existing maven project and point it to the pom.xml file. Maven will download all the jars and plugins required in the POM, and GPE will configure the project with the GWT and/or App Engine SDKs from the POM. You can then run Maven commands externally or Run As | Web Application in Eclipse.
  9. Testing. Run As | GWT JUnit Test lets you easily run test cases that extend GWTTestCase.
  10. SpeedTracer. You can launch SpeedTracer from within Eclipse. Click the green stopwatch icon on the GPE toolbar. GPE will compile your app, run it, and launch SpeedTracer in Chrome to profile your app.
Haven't tried it yet? Install Google Plugin for Eclipse now.

Update on GWT support for IE9

Posted by David Chandler - Friday, March 18, 2011 at 6:14:00 AM

In keeping with the GWT philosophy of making it possible to write no-compromise AJAX in any modern browser, GWT 2.3 (in progress) will support IE9. We're adding a new user.agent property "ie9" and the notion of fallback properties, so any browser-specific bindings not yet implemented in ie9 will fall back to ie8 and show a compile-time warning that a fallback impl was used.

In the mean time, you can tell IE9 to behave as IE8 by inserting the following in the head section of your GWT host page:

<meta http-equiv="X-UA-Compatible" content="IE=8" />

Assuming that IE continues to maintain backward compatibility, you may want to insert the equivalent tag for IE9 once GWT 2.3 ships in order to make your app somewhat future-proof for future IE versions. For more information on document compatibility in Internet Explorer, see http://msdn.microsoft.com/en-us/library/cc288325(VS.85).aspx

The IE9 dev mode issue reported back in Dec is fixed in GWT 2.2.0: http://googlewebtoolkit.blogspot.com/2010/12/support-for-gwt-dev-mode-in-ie-9.html

You can follow the status of known IE9 issues here:

Last Call for Google I/O

Posted by David Chandler - Monday, March 14, 2011 at 8:45:00 AM

For those of you who were quick to register, we thank you for continuing to support our developer initiatives -- this year's I/O is slated to be one of our best yet. For the rest of our developers, we weren’t kidding when we told you we <3 our developers.

Starting Wednesday, March 16, we will be launching Last Call for Google I/O: A contest that spans 10 days, 10 developer challenges and 100 chances to win tickets to attend the now-sold-out Google I/O 2011.

To participate, see the official Last Call for Google I/O blog post.

The GWT / Developer Tools contest opens Wed Mar 25 at 9am PST.

Styling and skinning your apps with TravelTripper

Posted by Fred Sauer, Developer Advocate - Tuesday, March 08, 2011 at 1:07:00 PM

There's more than one way to skin a GWT app. In this guest blog post, Erik Uzureau, User Experience Engineer at TravelTripper, shares their approach.

--

Styling/Skinning RezTrip

At TravelTripper, we make hotel reservation software. Our main product is a "booking engine" called RezTrip, a web based application that allows visitors of a hotel’s website to directly book a stay with that hotel.

As GWT applications go, we think RezTrip, when it comes to the question of styling, presents an interesting departure from traditional development. As a "white label" application, we needed to create our app in such a way that allows our hotel clients the ability to customize not only the "frame" around the application, but also the internal style of the application itself, such as fonts, colors, etc.

In other words, each hotel needs the ability to create their own custom header, footer, or sidebar and have it wrap the booking "application" portion of the page. Furthermore, each hotel needs to be able to change all the colors, fonts, and even some icons within the application.

The desired end result is a single booking engine application, running on multiple web sites, but always mimicking the look and feel of each individual hotel site.

We have two additional constraints:

  1. Cost - While our first priority is building a system with ultimate flexibility, the time spent to create each customization represents a direct bite into our profit margins. The business guys were explicit about keeping these costs to a minimum.
  2. Dynamic Changes - Clients are naturally picky about the appearance of their website, and their tailored booking engine is no exception. Experience told us that we would be fielding constant requests to tweak different aspects of the customized properties. This has to be easy to do and have minimal impact on the overall site performance.

Satisfying our Constraints

Keeping Costs Low

Our in-house GWT team is top-notch, but expensive. The previous version of our application was built on basic JSP/HTML/CSS technology, and the customization work had been done by a more affordable entry-level web designer. Similarly, for this version of the application, we wanted to limit the involvement of our GWT developers as much as possible, where possibly leaving stylistic tweaks to our web designer.

We want the customizer to be able to do *all* the work, without requiring any Java or GWT knowledge.


Making Changes Easy and Harmless

We realized that GWT's application compilation philosophy changed a lot of our longstanding web development assumptions. We didn't want to create custom UiBinder files for each hotel's frame, or have to make spot changes to CSS that would require a full recompile and redeployment of the application.

We want to be able to make CSS changes without recompiling or redeploying the app.

Our Solution

The only way to satisfy the above two constraints is to have all the customization work happen in simple HTML/CSS files that live outside the GWT project and WAR directory. This allows the customizer to work in pure HTML/CSS, directly with the files on the server, without ever having to modify the internals of the GWT application. Changes can take effect immediately, without a need to redeploy the app.

The Application Frame

We decided to have a separate index.html file for each property's customization. This allows custom header/footer/sidebar HTML, CSS and JavaScript to be included in the hotel's main page.

Another challenge for us was the need for the application portion of the booking engine to be able to be dynamically resized relative to the user's browser. To accomplish this, we decided to use a DockLayoutPanel, which handles the separation between the main application and the custom frame. We load an empty SimplePanel into each of the North, South, West, East sections of the DockLayoutPanel, and our application in the Center.

Next, we add special code that runs directly from onModuleLoad() that scours the host HTML document for four DIVs with 4 unique ids: tt-Header, tt-Footer, tt-EastSidebar, and tt-WestSidebar. If the app finds a DIV with those ids, it loads it into the corresponding SimplePanel and auto-sizes to the contents. If no corresponding DIV is found, the app hides the SimplePanel entirely and sets the width or height to 0.

What this means is, that the customizer doesn't get to lay out the HTML page exactly like it will be displayed when live. Instead s/he must smash the relevant content into the four qualified DIVs. This is a minor annoyance, but at the end of the day, the code itself is still the same basic HTML/CSS/JavaScript, and so it is perfectly manageable by the web designer. The GWT application is already compiled to super-fast JavaScript, so there's no need for the customizer to know any GWT. Instead, the customizer can just edit the contents in the HTML file and hit refresh to see the changes.

The CSS

Here again, we had to come up with a custom solution. To avoid the recompile/redeploy issue and also to keep it simple for the customizer, we had to handle the CSS for customizing the application without having to modify any code inside the GWT project.

What we ended up doing was creating three levels of CSS:

  1. UiBinder - Any time we needed to use a CSS style to adjust the size or layout of a widget or panel, we kept that CSS code in UiBinder XML. We only want the actual GWT developers to change the layout/size of the UI elements, so they needed to be in a sense “hidden” from the customizer. We loved how the default UiBinder behaviour is to generate md5 class names, allowing us to create lots of custom CSS rules, without worrying about namespace overlap and also ensure that the customizer would know not to override them.
  2. master.css - Next, we created a "master" CSS file where we put all the other CSS styles, which we thought were fair game, to be overridden by the customizer. This is a huge CSS file, but when minimized (yuicompressor) and gzipped, the end result was still better than the latency hit we had when originally we tried to spread these across multiple files (for organizational purposes). Note that the master.css file is loaded directly from the main HTML file.
  3. designer.css - The final layer is the "designer" CSS, which is where we have the customizer put all the CSS rules which override the defaults. The class names in this file all match the class names in the master CSS, but since we load the designer CSS in the page *after* we load the master CSS, the former will always override the latter.

Summary

Despite our constraints, we were able to configure our GWT application to perform exactly as we desired. Our application is fully customizable, both in terms of the surrounding frame layout and also the internal application's colors and fonts, all without the customizer having to know any Java or GWT. By carefully separating the different layers of the app, we were able to make it easily and efficiently customizable on the fly, without ever having to redeploy the application.

Sample index.html File

<!DOCTYPE html>
<html>
  <head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">

  <title>Paradise Hotel Reservation System</title>

  <!-- Master CSS File -->
  <!-- All styles in here can be overridden in designer.CSS (below) -->
  <link rel="stylesheet" href="../reztrip/CSS/master.CSS" type="text/CSS"/>

  <!-- Designer CSS File -->
  <!-- Single css file to be created and modified by the customizer. -->
  <!-- New styles for the frame and overridden style from master.CSS go here -->
  <link rel="stylesheet" href="style/designer.CSS" type="text/CSS"/>

  <script type="text/javascript" language="javascript"
          src="../reztrip/reztrip.nocache.js"></script>
  </head>

  <body>

  <div id="tt-Header" class="tt-Frame-Header">
    <!-- because tt-Header has content, we will load it and auto-size -->
    <!-- it in the header area of the application frame -->

    <table class="tt-Frame-HeaderTable">
      <tr>
        <td>
          <img src="img/paradise_logo.png"></img>
        </td>
        <td>
          <img src="img/paradise_menu.png"></img>
        </td>
      </tr>
    </table>

  </div>

  <div id="tt-Footer" class="tt-Frame-Footer">
    <!-- empty, so no footer will load -->
  </div>

  <div id="tt-EastSidebar" class="tt-Frame-EastSidebar">
    <!-- empty, so no east sidebar will load -->
  </div>

  <div id="tt-WestSidebar" class="tt-Frame-WestSidebar">
    <!-- empty, so no west sidebar will load -->
  </div>
 
  <!-- OPTIONAL: include this if you want history support -->
  <iframe src="javascript:''" id="__gwt_historyFrame" tabIndex="-1"
          style="position:absolute;width:0;height:0;border:0"></iframe>

  </body>
</html>