Friday, June 1, 2012

GWT - Flash - Swing [Lessons learned]

Approximately one year ago I joined a new startup company and had to decide what technology would be used to build a new highly graphical application.  The requirements were :

  • display dashboard pseudo realtime charts and tables
  • display graphs of objects and their associations and links
  • make it feel like a state of the art application with some coolness factor
  • make it usable and intuitive
  • make it scale
So I built some sample screens using Java Swing, the Google Web Toolkit and Adobe's Flash.  I was able to somewhat build the same screen using each of these technologies.  Long story short.....Java Swing was eliminated since we wanted to run in a web browser with no installation required.  Adobe Flash was eliminated since it would not run on various Apple devices and required a lot of specialization.  This left the Google Web Toolkit.  I had never used it, but had just come off learning Oracle's ADF Technology which actually has a lot in common.   Also, the development environment would be Java with Google doing the javascript generation for me. Being a Java Swing expert put me right in the driver's seat.  

- Advice to any Java Swing experts out there.....learn GWT.  It's a very easy transition. -

To get a jump, I bought the Essential GWT book and started reading and experimenting.  I also started reading and experimenting with the copious online documentation about GWT.  Turns out that the stackoverflow web site would prove extremely valuable for answering detailed technical questions.

My first task was to architect the directory structure and modeling for the application.  Using a MVP (Model, View, Presenter) model was the way to go.  This would allow me to later change the view code to use any widgets (maybe Droid stuff?) without changing the model or presenter code.  I may never do this with my application, but at least it's architected to get there someday.  In a nutshell, the View classes do the widget creation and layout.  The Presenter code handles all callbacks and handlers to push data to the widgets.  The Model code gets data from my db into data structures that I can access asynchronously using rpc AsyncCallback mechanisms.

Everything seemed to fall into place as the application was built.   A spot for images, dialogs, events, tables, panels and third party javascript integration was created.  At this point, any new feature is more of a cut and paste of an existing feature, which is exactly where a product starts to mature.  

I am very impressed with the GWT performance as well.  Drawing tables and charts and lists is very quick and efficient.  Integration with some javascript tools has been quite easy and reliable with the JSNI implementation.  CSS overriding of the GWT widgets has allowed me to completely brand the application to our company style and give it a sophisticated look and feel.  No gwt-ext or ext-gwt here.

Here's to releasing the product and showing some screen shots here soon....




Tuesday, March 20, 2012

Auto Refreshing Your UI?

It seems that forever, there's been this battle between building an application that automatically refreshes when data changes or provides the user with a refresh button to press at their leisure. One can see the benefit of both. Let's say your interface is displaying a large graphical map of data that a user has sized, shaped, and customized to their liking. In comes a database update (probably from another user) and the application automatically redraws the graphical map, removing all the customizations that the user has spent time doing. Not good. Maybe lighting up a "refresh to see new data" button would have been better in this case.

Let's say a user is looking at a table of data showing objects and statuses. Due to an event in the system, one of the objects has gone from a green status to red. This is a case where an automatic refresh is in order otherwise how will a user know of this change in condition?

So given different circumstances, multi-user applications, event processing applications and the like, how can I build an application that automatically refreshes. My goal has always been to never have a "refresh" button on my menu bar. Having one, shows an application that has not been architected or designed for ultimate ease of use and an application that some users might find broken or out of date frequently.

Real World Example

Using GWT for my application development, I built a GWT UI server backend that my UI clients connect with asynchronously to "get" and "set" data. A hibernate DB backend server allows my GWT UI server to "get" and "set" data via a REST api. So all the moving parts are nicely in place. A DB storing all the data, a UI server that interfaces with the DB server and provides asynchronous data to any UI client that connects to it.

How to keep a client view auto refreshed?

The first part was to get my UI server in sync with the DB server. In one of my UI views, I show a table to objects, let's call them "widgets". These widgets have a name, description, update date and a status. My UI client will ask my UI server for a list of these objects to then feed into my GWT table. My UI server could make a call over to the DB server to get these objects, but how to keep in sync with changes that can occur and how to make this perform ok?

The Magic.

Upon initial connection and startup, my UI server gets all of the "widgets" from the DB server and stores them. It then starts a timer, going off every second, which ask the DB server via REST, if any of these widgets has changed (created, deleted, modified). For the most part this call returns "nothing to do" and the timer goes back to sleep. However, a key part of this is that my UI server always has the latest data in its data structure and always keeps it up to date (at least within a second or two). If a change does occur, the UI server data structure is updated and a date stamp is created for this update.

Along comes a UI client that connects to the UI server and asks for the widget data for the GWT table. The UI server already has a data structure ready to go and returns the data instantly to the client. The table is drawn. Any other UI clients connecting will get the exact same results. All the UI clients share this UI server. When the UI client has completed populating and displaying the table, it in turn starts a timer. Each time the timer goes off, it asks the UI server if any of the "widgets" have changed. The UI server returns the date stamp of the last change and UI client uses this to determine if it already saw this change or not. If not, the UI clients get the new data and updates the GWT table.

In summary, the UI server's job is to ask the DB server about changes using a timer and keeps the data structure up to date with the DB. The UI client's job is to ask the UI server about any changes it has, also using a timer. Since all UI clients share the same UI server, they are all in sync all the time and all see the same underlying data.

In demoing my application, I always get the comments of "this application is very fast" and "it sees updates very quickly", and of course "why don't all application refresh like this?"

In a future blog, I'll cover this more with some sample code and diagrams. For now, give you users the most usable application you can. Software is great at the mundane tasks....updating data structures!





Thursday, January 26, 2012

Steve Jobs Biography

For Christmas I received Steve Jobs biography. My family knows that I work in high tech and that I design user interfaces and applications and fell in love with my recent MacBook Pro, my first "Apple" product.

This is the first book that I've read cover to cover in quite a while. Most of my reading is technical articles, blogs, online books, etc. where I only have a few minutes to figure something out, learn a new technology or get an answer to a technical question.

As I went through the book, it became very nostalgic. I started my career in the early 80's at Digital...saw the first PC they made, saw a "color" screen appear and this thing called a mouse too. I look back now and feel so lucky that I was part of the user interface group, designing applications using DECWindows (and later Motif) and working with the User Interface lab, observing users and learning how someone interacts with a device. The whole interaction and experience is what has differentiated Apple from the beginning and was driven by Steve Jobs. Sure, they came up with great devices that did wonderful things and were so cool, but so did others, it was just that theirs were so elegant, simple and user friendly.

I look at the user interfaces I have designed and that I continue to design and I now have a more critical view of them. When a user lands on my screen, do they know what to do? Does it make sense? If they do the wrong thing, is it clear why that operation didn't work and what they should do instead? Do they need to read a manual to figure it out?

It is fascinating to me that since 1980 to now, 2012, UI design really hasn't changed at all. Buttons, menus, scrollbars, trees, tables, etc. are still the same. Just like an artist with a canvas and paint, it's the combination of colors, layout, textures that make his painting into art. Those who can take a complex set of data and a complex task and make into the most simple, logical, and easy operation end up with the most usable products.

I judge my applications by my users. How quickly are they doing productive work with it? Can I get them to the right screen with 1 click or 1 touch or 1 operation? Is my Product Manager out demoing and using the application without asking me anything about it? No one reads the manuals these days. The application has to "just work."

So today I work on user interfaces developed with GWT. I also design products for the Android interface. Any feature or layout or function I can imagine can be done with the GWT widget set. Any look or color or size or shape can be done with CSS. For Android, a smaller/touch screen presents a different set of challenges, but really forces me to think even simpler, more straightforward and work towards an elegant solution.

Steve Jobs was very demanding, knew what he wanted and would not be happy until he saw it and reading his biography has certainly left a mark on me. Steve thought something was total crap, horrible, unusable until one final tweak made it "perfect." So strive for quality - prototype - adjust - rework - open your eyes to the environment around you - and shape your work into something elegant. You are one tweak away from perfection.



Wednesday, December 14, 2011

Doing that cool reflection thing....

We've all seen applications, websites, tv advertising, logos, etc. that have a reflection under them. It's the new cool thing to do. I'm sure there are probably many ways to do this, but I'll share in this blog one way that I did it with my GWT based application.

I'll start with the end result that I achieved...our login dialog box:



First, I built a panel that has a background gradient and rounded edges on the border. It's a GWT FlexTable with a css style setup.

final FlexTable loginFlex = new FlexTable();
loginFlex.setStyleName("my-DialogStyle");

Inside my CSS file, I have:

.my-DialogStyle {
background: #FFFFFF;

filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFF', endColorstr='#999999'); /* IE compatible */
background: -webkit-gradient(linear, left top, left bottom, from(#FFFFFF), to(#999999)); /* Webkit compatible */
background: -moz-linear-gradient(top, #FFFFFF, #999999); /* Firefox compatible */

border:1px solid #666666;
border-radius: 8px 8px 8px 8px;
-moz-border-radius: 8px 8px 8px 8px;
-webkit-border-radius: 8px 8px 8px 8px;

padding: .5em 2em .5em 2em;
}

Once I had this working and appearing on the screen, I then needed to make the reflection. To do this, I found this web site:


http://www.generateit.net/reflection/index.htm

You load up your image, which for me was a screen shot of my login dialog. You pick how much reflection you want (I picked 20%) and your background color (which for me was white). The web site generates a PNG file that you can save.

In my case, I only wanted the reflection part of my image, so using a graphics tool (like Photoshop, or PaintShopPro or Gimp) I captured the reflection part into a new PNG file:




The last step was to draw my reflection on my screen "attached" to the bottom of my login dialog box and center this on my screen too. I used a LayoutPanel to hold my FlexTable and my reflection image:

final Image reflection = new Image(loginreflection());
final LayoutPanel mainPanel = new LayoutPanel();
mainPanel.add(flexPanel);
mainPanel.setWidgetTopHeight(flexPanel, (Window.getClientHeight() / 2) - (flexPanel.getOffsetHeight() / 2), Unit.PX, flexPanel.getOffsetHeight(), Unit.PX);
mainPanel.setWidgetLeftWidth(flexPanel, (Window.getClientWidth() / 2) - (flexPanel.getOffsetWidth() / 2), Unit.PX, flexPanel.getOffsetWidth(), Unit.PX);

mainPanel.add(reflection);
mainPanel.setWidgetTopBottom(reflection, (Window.getClientHeight() / 2) + (flexPanel.getOffsetHeight() / 2) + 1,Unit.PX, 0, Unit.PX);
mainPanel.setWidgetLeftWidth(reflection, (Window.getClientWidth() / 2) - (flexPanel.getOffsetWidth() / 2), Unit.PX, flexPanel.getOffsetWidth(), Unit.PX);

For a really cool effect, you can also add:

mainPanel.animate(1000);

but animation is for another blog. Enjoy!

Saturday, October 1, 2011

GWT Tricks #2

I want to have a dialog box or a display on my screen where the user can just hit the "Return" key and not have to click on my OK button. It might be a data entry form and they are typing, tabbing, typing, tabbing and should not have to take their hands off the keyboard to finish...just hit Enter or Return.

To do this, you'll need to create a class for your button that listens for a Key down. Here's how:

1. First create a class that you can reuse on any form or display you like:

public class ButtonPressListener implements KeyDownHandler
{
private final Button button;

public ButtonPressListener(final Button button)
{
this.button = button;
}

@Override
public void onKeyDown(final KeyDownEvent key)
{
if (key.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER)
{
button.click();
}
}

}
This class will see a KeyDown event, check that it was the Enter key and then press your button. So if you pass in your default button or OK button, it gets activated when the user presses enter. Here's how:

First create your button -
private final Button    okButton     = new Button();
okButton.setText("OK");
Now create your listener, passing the button you want activated when the user hits Enter -
final ButtonPressListener listener = new ButtonPressListener(okButton);
Now, if your dialog box or form has other input fields, you want each of them to see an Enter key press and activate your OK button. In this example, we have a username and password field on our screen:
usernameTextBox.addKeyDownHandler(listener);
passwordTextBox.addKeyDownHandler(listener);

Now that you know how to setup a key listener, you can create all sorts of conveniences for your user and let them fly through your UI screens.

Thursday, September 22, 2011

GWT Tricks #1

I've decided to post any "tricks" or common GWT mistakes that I've run into, researched and fixed. Hopefully these will be helpful to the next person who sees the same errors, researches the same information and wonders which fix to "try".

The SafeHTML warning

Ever see these warnings when running your GWT application?
[WARN] Template with variable in CSS context: The template code
generator cannot guarantee
HTML-safety of the template -- please inspect manually
What does this mean? How do I fix it?

Basically, it is telling you that you have inserted an "include" in your code to something in a .css file. Look for something like this:
sb.appendHtmlConstant("<div class=<\"myapp-CellSelect\">");

Where the myapp-CellSelect happens to be defined in your myapp.css file. Since you are bringing something in from "outside", the code generator can't insure it's going to work. That "outside" thing may be broken, missing, or malformed and is a bug waiting to happen.

So, what to do?
Remove this external reference and put it inline with your div. So, let say your: myapp-CellSelect is:

.myapp-CellSelect {
text-decoration:underline;
cursor: pointer;
}

then your code should look like:
sb.appendHtmlConstant("<div style=\"text-decoration:underline;cursor:point\">");
You no longer are pointing to something in your .css file and the warnings will now be gone.


Auto Selecting an Input Field

When implementing data input screens, like popup dialog boxes for example, you sometimes want to set the focus in the dialog box to something meaningful. Maybe this data entry screen has a Name field followed my other input fields. It might be nice to automatically select the Name field for the user so that they can just start typing when this popup opens. In typical application programming, you can just set the Name field as the initial focus field and it works, however, with web/GWT programming, this will not work as you expect.

Take this example:

TextBox nameBox = new TextBox();
nameBox.setFocus(true);

build the rest of your fields, populate them with data and then show() the dialog. The nameBox is not highlighted, not focused on, not ready for user input until they click on it. Why? Because the setFocus must be called after the dialog box has been rendered. Ok, so what to do?

In the code that will do the: dialog.show(); call, set the focus to the field you want when the system is not busy, meaning right after it has rendered your dialog. How? Like this:

Scheduler.get().scheduleDeferred(new ScheduledCommand()
{
@Override
public void execute()
{
nameBox.setFocus(true);
}
});

dialog.show();

Remember, with GWT there are a lot of async operations that might happen. In my case, I make calls to my database to fill in my dialog and then once they have completed, I show my dialog. Had I tried to setFocus at the beginning, it would have failed. Setting focus at the end works.

Tuesday, September 13, 2011

Patent Issued

Today I received notice that my name was included on a patent. The process was long, the company actually came and went during the whole process, but still, it happened, it's permanent and it's kinda cool. At least to me...

I'm including a link to the patent details here and I truly don't remember all the ins and outs of the algorithm, but I'll try to describe it here.

The Patent

As a UI developer, I'm always worried about keeping the data I'm showing up to date. Almost all systems require multi-user support and once someone sees stale data or worse, tries to edit it, all heck breaks loose. Your application takes a hit, your users start to feel worried about the data integrity and you'll scramble to try and "fix" it.

From the UI point of view, your widgets, tables, trees, views should be backed by "backing" data in the form of some kind of data model. Processes need to be in place to keep that "backing" data up to date and then your widgets need to react to that data changing and do the right thing. This is usually achieved with some kind of polling or pushing. When done right, your users will be amazed and feel very good about the application.

At Quarry Technologies, a secure router was being developed with a configuration CLI (command line). The UI application would need to latch on to a router and push configuration commands at it. Now what happens if someone were to telnet into the router, get onto the command line and start making configuration changes? The UI would be instantly out of date. The configuration screens and data would be stale. The rules engine for validating configuration changes wouldn't be useful, etc. And what if there were multiple UI's and multiple command line jockeys all going at it. Chaos would ensue! and it did....

How to solve this? What if there was a way for the router to tell everyone interested about configuration changes? After all, the router held that final configuration at all times and insured consistency. So we developed a way for the router to essentially "echo" out to all listeners configuration changes as they were accepted and processed. Now the UI application could setup a listener and process configuration changes coming from the router. This sounds simple enough, but there was more to it than that....you can read the goodies in the patent....but in a nutshell, the ability for our router to intelligently push out a consistent state of its configuration to all listeners was the big deal.

So I guess someday my kids, grandkids, etc. can look me up on Google or whatever the worldwide search engine will be and see my name on a patent. Here's to more to come....