Wednesday, April 23, 2014

An Application Within An Application

Sometimes you set out to build something and it takes on a life of its own...maybe even having a different use that you originally intended.   I've always been amazed at how software applications and languages, given a set of features and functions, can be used to build something amazing, something that the original developers never knew could be done.

They say a picture is worth a thousand words.  Nothing could be more true than trying to visualize how a network is put together.  Even walking into a lab or server room and looking at the racks and cables and systems leaves a lot to be desired.  How are my applications communicating?  What are the conversations going on in my network?  What has discovered what?

The Plexxi Control networking view needed to show this information.  Tell me about my Plexxi Switches and what they know about.  What traffic are they carrying?  Who's talking through them.  So we built a network visualizer to show the Plexxi Ring and a handful of networking device types:


We'd display our ring, the connected switches and "buckets" of machines, storage and virtual hosts/machines.  But what about routers and switches and other machines, generic machines, etc.  How can I put these on my diagram to better define my customers network?

Given our ability to display a set of objects and their connections, why not open this up to additional types of objects?  Why not allow the customer to define their own icons (maybe they use Juniper gear or Dell or Cisco or HP)?  Why not allow these new objects to be connected wherever the customer wants?  We can extend our network visualizer to do this...



And so, with just a little more code and a few more "Element" features, our basic network display tool has morphed into a full fledged network visualizer.   We can use it to build just about any network diagram.  We can get a better picture of what's connected where and how our communication is flowing.   Our network application is now a network visualization application too. 

I think I can hear the Plexxi product managers already thinking about a fancy "print" function to take a large network and stick it up on their wall.

Wednesday, November 6, 2013

The Most Useful Dialog I've Ever Built

For many years, I've been lucky to work on some very cool, interesting, fun, and important projects.  Sometimes, when you are fully immersed in the technology you are building, you don't always see the big picture.  Later on, you might be able to look back and fully grasp what you designed, what you built and how someone might actually do something useful with it.

I thought that my very first project, coming out of college and joining Digital Equipment (DEC), was the coolest thing.  It was called DECplan, a project planning and management system.  Remember Gantt Charts?  Precedence Diagrams?  Project Schedules?   I was tasked with "reports".  That's it.  Build a way for users to get reports out of the system.  I designed and built the Report Layout Editor.  A way to take a blank sheet of paper and customize a report.  Basically, drag database fields onto the page and then "generate" the report.  Looking back, our group built Microsoft Project before there was even a Microsoft.  I had no idea that I built a Microsoft Word like interface with one of the first graphical toolkits in the industry....DECwindows.  Very useful.


Next stop, Wellfleet.  A small networking company that had grand plans of doing big things... and it did.  As it grew, to Bay Networks and eventually Nortel Networks, I was lucky to be on the team that was tasked with managing *ALL* the networking products....routers, switches, hubs, and on.  Our lab was huge, with one of every product in the companies offering.  The interface (now using SUN equipment with Motif) had to show all the different devices, each with unique settings, fields and options, in a generic way that allowed for ease of use.  This was a challenge and a success as it did display all the equipment it discovered in a single cohesive view.  Very useful.

Virtualization was born.  An industry that has spawned numerous companies and has provided thousands of jobs to this day.  Now using Java and Swing and being able to really build not only a useful application, but something that was pleasing to use and visually intriguing, was the next challenge.  I was lucky again, to land in the fast paced startup world in the middle of an emerging technology company, Virtual Iron.  Design and build an application for managing virtual machines.  Show me what's running, allow me to rollout new machines quickly and put it all at my finger tips.  Very useful.



Along came SDN.  To be fair, SDN occurred a few years after I had already started at my next lucky stop, Plexxi Inc.  Long before network overlays, SDN, DevOps integration, and all the present day technologies started coming together, Plexxi was already working on it.

Design and build an application that shows me application conversations in my network, lets me put policies on those conversations, automatically adjust my network and show me the results.  Wow.  Of course this would be the most useful application I've ever built.   Then, one day, well into the development of Plexxi Control, the subject of DevOps and troubleshooting and network management came up.  I need to find something in my network, but I don't know much about what I'm looking for.  Maybe I know the IP Address, maybe a name, maybe a type of object, maybe a MAC Address.  Help!

And there it was, "The Most Useful Dialog I've Ever Built."



Can you find this for me?  Do you have this object in your controller database?  What's the name? Do you know the MAC or IP address?  What operations can I do to it?  Which Plexxi Switch sees this object?  What port is it seen on?  Is it on a VLAN? Is it Affinitized? 

It may seem simple, but being able to access and display this kind of information from our central controller helps answer ( in a single press of a "Find" button) a very complex question, that typically involves querying several applications, people, spreadsheets, emails, and all sorts of disorganized network information.  Very very useful.




Thursday, June 27, 2013

Show Me An Affinity

- Simplifying Complex Processing with a User Interface -

Every application I have ever worked on had the same end goal; provide useful, simple, easy to use and visually appealing screens.  Don't confuse me.  Don't make me click hundreds of times.  Don't leave important information out.  If something fails, tell me what to do next.

In designing a set of views and screens for my current project, the problem statement can be summarized as follows:
  • Show me where my applications are in my network
  • Let me pick the important applications and designate them as such
  • Let me define how these applications should be conversing
  • Do some SDN magic on these applications
  • Show me where my applications are in my ring
Providing the ability to see and do all of these actions requires a full application suite where common information is displayed from different perspectives.

In my Network view, I can search for specific virtual machines, among other things, and put them into an affinity group, thereby capturing the importance of an application in my network.





I am interested in how my three applications:
  • authhost71
  • authbox81
  • authclient62
converse with their backend databases dbserver28 and dbserver84. 



Everything in App1 talks with DB1, bidirectionally,  and I'd really like these conversations to be isolated from other ring traffic.

Is my ring ready for the SDN magic fitting algorithm to do it's thing?    Looks formed, healthy, good to go.



For each of my conversations, where are my applications traversing the ring?  My fitting results shows me how each application in App1 talks with each application in DB1; where it enters my ring, how it traverses my ring and where it exits my ring.





I found some applications in my network and after affinitizing them ("is that word? affinitizing?  it will be soon...."), I see clearly how my ring is handling their conversations and isolating them from all others. 

Taking a complex set of data and simplifying the ability to work with that data is what a good user interface is all about.   Show me an affinity? I saw an affinity today.





Friday, March 15, 2013

Fun with JIT, part2

Here's some more neat things I've done with my GWT JIT integration.  The code snippets here are to represent what is possible and your mileage may vary.

Dragging Objects

In many of the JIT renderings, you can drag objects around the screen and can have full control over what you allow to be dragged.  You start by getting a callback when dragging is occurring:

onDragMove : function(node, eventInfo, e) {

where the "node" is the object that is being dragged and "eventInfo" has position information.  For a Force Directed JIT graph type, to allow dragging of your objects, you simply do this inside the onDragMove function:

var pos = eventInfo.getPos();
node.pos.setc(pos.x, pos.y);
fd.plot();

By the way, "fd" is an instance of the Force Directed graph.

As you drag the object around the screen, it will be moved and the graph will be replotted to show the update.  If the object you are dragging has any edges attached to it, they will automatically be moved as well.  But what if you have relationships on your display?  What if you have a parent object that has several children connected to it and when you drag the parent, you want the children to be dragged as well.  At Plexxi, we display a RING object with Plexxi Switches connected to the ring.  If a user drags our ring object, we want the switches to go with it.  Here's how:

onDragMove : function(node, eventInfo, e) {
    var pos = eventInfo.getPos();
    if (node.getData('type') == "plexxiring") {
        node.eachAdjacency(function(a) {
            childnode = fd.graph.getNode(a.nodeTo.id);
            childnode.pos.setc(childnode.getPos().x - (node.getPos().x - pos.x),
                                          childnode.getPos().y - (node.getPos().y - pos.y));
        });

    node.pos.setc(pos.x, pos.y);
    fd.plot();

What we do is get all the nodes connected to our dragged node and move them as well.  This performs surprisingly well in our application.  You can take this further and re-curse through all your objects moving even more when a single one is dragged.

Mouseover Tool Tips

On some occasions, you may want a tooltip or a text box to show up on the screen as the user moves the mouse over your nodes.  To insure good performance, you will want to add the tooltip text to a private JSON data object so that this text is instantly available to you at any time.  If you have to go back to your database of make some other calls to get your tooltip text, you may suffer from bad performance in rendering them. 

Here's how I did Tips with my Force Directed graph:

Tips : {
    enable : true,
    type : 'Native',
    offsetX : 10,
    offsetY : 10,
    onShow : function(tip, node) {
        tip.innerHTML = node.getData('tooltip');
   },


Auto Refreshing

One of the biggest issues with any graphical application is refreshing.  Does your user have to press a refresh button?  Does that waste time retrieving data from your database, destroying whatever you are currently displaying and rebuilding the display with new data? 

By using GWT and the built-in RPC mechanism, I am able to ask my GWT Server if any data has changed and then act of it.  This is a topic for another blog....but let's say my Force Directed graph is showing 5 different types of objects on it.  I ask the GWT Server to coordinate with my backend database to keep a cache of the objects I'm displaying and if any of these objects is modified, or deleted, let me know.  When I find out something that I am displaying has changed, then I take action.  The most common events are creating or deleting a link (edge), deleting an object or changing the name of an object.  Here's how they are handled as called by my GWT code:

private native void createLink(JavaScriptObject nativeGraph, String link, String from, String to)/*-{
        if (nativeGraph.graph.getAdjacence(from, to) == null) {
            var fromNode = nativeGraph.graph.getNode(from);
            var toNode = nativeGraph.graph.getNode(to);
            var adj = nativeGraph.graph.addAdjacence(fromNode, toNode,
                            {
                                'linkUuid' : link,
                                'selected' : 'false',
                                'linkcolor' : '#FF0000'
                            });
              
        nativeGraph.plot();
    }
}-*/;

private native void deleteLink(JavaScriptObject nativeGraph, String linkUuid)/*-{
        nativeGraph.graph.eachNode(function(n) {
            n.eachAdjacency(function(a) {
                if (a.data.linkUuid == linkUuid) {
                    a.setData('alpha', '0');
                    nativeGraph.graph.removeAdjacence(a.nodeFrom.id,
                            a.nodeTo.id);

                    nativeGraph.plot();
                    return;
                }
            });
        });
    }-*/;

private native void deleteNode(JavaScriptObject nativeGraph, String nodeUuid)/*-{
        nativeGraph.graph.eachNode(function(n) {
            if (n.id == nodeUuid) {
                n.setData('alpha', 0, 'end');
               nativeGraph.removeNode(nodeUuid, {
                     type: 'fade:seq'
                    duration: 1000, 
                    hideLabels: false 
                    transition: $jit.Trans.Quart.easeOut   
               });
            }
        });
 }-*/;


private native void updateNodeName(JavaScriptObject nativeGraph, String uuid, String newName)/*-{
        var node = nativeGraph.graph.getNode(uuid);
        if (node != null) {
            node.name = newName;
            nativeGraph.plot();
        }
}-*/;

fun with JIT part3 might be in the works......enjoy.





Friday, January 18, 2013

Fun with JIT, part1

Over the past year, I've been integrating JIT  (thejit.org) with my GWT application.  Javascript is not something for the faint of heart and personally I try to stay far away from it instead allowing  GWT to generate the Javascript for me based on my Java implementation code.  But to make use of, extend, and better control the canvas based layout tool JIT, I had to take on some Javascript.  So here's some things I did with it.  Any code snippets here should be considered pseudo-code and are for representation only.


Saving & Restoring Node Positions

The Force-Directed Graph has a built in layout algorithm that draws a graph as best as it can.  However, each time the graph is rendered, the layout algorithm produces a different layout.  We offer the user the ability to control the layout somewhat, specifying spacing between nodes and how many iterations the algorithm should use based on a complexity setting and some others:


Once the layout has been run, we then let the user drag the nodes and links around the screen to better position items to their liking.  To fully make this work, we need to save the node positions so that the next time we view the graph, we put all the nodes back into their original positions.  This also provides a big performance boost, in that we never run the layout algorithm a second time, but instead tell JIT where we want the nodes.

Save Positions:

// We store the node positions using our string object id, and the x,y values.
HashMap<String, ArrayList<Integer>> nodePositions;

// We iterate over the graph, getting the positions of each node.
mygraph.graph.eachNode(function(n) {
saveNodeData(n.id, Math.floor(n.getPos().x), Math.floor(n.getPos().y));
});

saveNodeData(String id, int x, int y)
{
    ArrayList<Integer> locations = new ArrayList<Integer>();
    locations.add(x);
    locations.add(y);
    nodePositions.put(id, locations);
}

Restore Positions:

// Lood our JSON data
nativeGraph.loadJSON(data);

// Put the nodes at the positions we want. No need to run the layout algorithm.

iterate over the saved node positions data and call this:
setNodePosition(JavaScriptObject nativeGraph, String id, int x, int y)
{
    node = nativeGraph.graph.getNode(id);
    if (node != null) {
        node.setPos(new $wnd.$jit.Complex(x,y), 'current');
        nativeGraph.plot();
    }
}


Resizing the Graph

JIT comes with some built-in functionality on many of their graphs that allows the user to scroll their mouse wheel which then causes the canvas to scale in and out, making the drawn objects grow or shrink.  I found this functionality to be somewhat difficult to control and also I wanted to control how large and how small I would allow the screen to scale to.  



I implemented two push buttons on my graph that allow the user to scale up or down as they are pressed.  One jumps 125% and the other jumps 80% which provides an even up/down scaling so that they user can always return to the default, 100%.

Scaling In:

Scaling in makes the objects larger.  Each time the user presses the "+" button, I ask JIT to:

nativeGraph.canvas.scale(1.25, 1.25);


Scaling Out:

Scaling out makes the objects smaller.  Each time the user presses the "-" button, I ask JIT to:

nativeGraph.canvas.scale(.8, .8);


Searching the Graph

Since my graph can get quite large with many of the objects off the edges of the viewable area, I implemented the ability to search for any node by name.  Once found, the node would be selected and the graph would be centered on the object, bringing the object into view for the user.  Here's how.


Find Node:

findNode(JavaScriptObject nativeGraph, String name)
{
    var p = new RegExp(name.replace("*", ".*"));
    
    nativeGraph.graph.eachNode(function(node) {
        if (p.test(node.name)) {
            // Found the node, we can get the x,y positions of this node.
    centerScreen(node.getPos().x, node.getPos().y);
}
}

centerScreen(String x, String y)
{
    // We are using a scroll panel with scroll bars as the parent of our JIT canvas
    // so we just adjust these scrollbars.
    graphContainer.setScrollLeft(((graphWidth / 2) -
(getOffsetWidth() / 2)) + x);
    graphContainer.setScrollTop(((graphHeight / 2) -
(getOffsetHeight() / 2) + y);
}

...More Fun with JIT, part2 coming soon.






Tuesday, December 18, 2012

All Artists Need A Canvas

In designing user interfaces, the widgets provide the starting point.  The widget set typically includes lists, tables, trees, buttons, menus, and dialogs, and provides the interface designer with his tools.   Mapping data into a tree or a table, styling the widgets for a branded look and feel, adding scrolling, sorting, and selection behavior brings a user interface to life and provides the end user with instant visibility.

But sometimes these basic widgets don't go far enough with their ability to convey real world concepts. If a picture is truly worth a thousand words, a graphical four column table with rows of data does not a picture make.  So what alternatives are there?  What if I need to display objects arranged in a circular fashion with relationships between them?  What if I need to show a grab bag of elements that share various connections with each other?  How do I give the user that one picture worth a thousand words?

Given my requirements, I went searching for my etch-a-sketch that would both allow me to arrange objects and at the same time help me with the organization of them.  Enter JIT - Javascript InfoVis Toolkit.  A compact, simple, extendable and powerful canvas drawing and manipulation tool that could be easily integrated into my GWT-based application that was already underway.

In conjunction with the JIT documentation, examples and experts on the Google-groups, I was able to build a view that would provide our users with a visual rendition of network components and their connections between each other as shown.

Network View


We achieved support for:

  • Search by name with the resulting object being selected and centered on the screen
  • User draggable elements for user positioning or JIT auto layout algorithm activation
  • Saving of all element positions to redraw later using the same layout 
  • Zoom in and Zoom out functions for canvas scaling controlled with a "+" and "-" button press
  • Spacing between elements, canvas size, font size and name truncation controlled with view options
  • Full element selection, extended selection and right click popups for shortcut operations
  • Full link (or edge) selection, extended selection and right click popups for operations
  • Dynamic view refreshing using "sum" and "morph" JIT technologies via JSON data
  • Much more to come....

What about being able to show a set of objects related to each other in both directions?  A set of elements that form a ring?  Something that supports selection and can show elaborate connections, but that auto layouts the diagram perfectly each time?

Ring View




With the sunburst layout we achieved support for:

  • Search by name with the resulting object being selected on the screen 
  • Zoom in and Zoom out functions for canvas scaling controlled with a "+" and "-" button press
  • Ring size and spacing, font size and name truncation controlled with view options
  • Full element selection and right click popups for shortcut operations
  • Link (edge) highlighting using various colors based on search or selection criteria
  • Dynamic view refreshing
  • Much more to come....

By combining the asynchronous processing power and speed of GWT with a simple javascript canvas drawing and manipulation tool, we are well on our way to building an interface that fills trees, tables, buttons, menus and dialogs and provides that thousand word picture.



Wednesday, October 10, 2012

You Can Go Home Again

Who says you can't go home again?

As a newly graduated computer scientist, my own backyard was full of companies to go to work for - Data General, Wang, DEC, Apollo, and others.  These companies were booming and were gobbling up my classmates.  Living in New Hampshire, I chose DEC and landed at the Spit Brook road facility that included the famous ZK1, ZK2 and ZK3 buildings.

I traveled to California, Vegas, even Valbonne France as Digital grew and grew.  I sat next to seasoned consulting engineers that knew how to build fantastic software.  I learned.  I saw the creation of computer graphics via DECWindows based on the X Windows framework and later to Motif.  I was hooked with UI design.  I originally worked on DECPlan (basically Microsoft Project before there was a Microsoft) and to this day, it had features that no project management system has.

Mid-90's....the downturn starts.  Competition heats up, the PC is born, Wang starts to collapse, DEC has layoffs and salary freezes, change is brewing.  After 10 years, it's time to move on.  There's some new up and coming companies called Cabletron, Wellfleet, Cisco out there that are the next big things.

And so, some 25 years after beginning in ZK3, I have returned to Spit Brook road.  It's no longer one company...the buildings have been updated, carved up to house numerous companies.  I recently took a walk to some of the uninhabited floors and areas.  I found a conference room with some very interesting information printed on the wall:




The list of VMS features spanned from BL5 (which boasted 100 customers) all the way to version 5.0. It was almost eerie.....like the engineers had just packed up and left and now only dust was living here.

The buildings have also undergone some cosmetic changes as well.  All the entrances have been redone, the heated outside tile gone, and a more engineered entrance in place.



The interior hallways have new carpet, and a new paint scheme with more modern lighting.



A piece of DEC history has also been restored.  Many old timers will remember the barcode on the entrance to ZK2, where the main entrance and credit union used to be.  It spelled out Digital  Software Engineering at some point and has long been removed.  But this past summer, this showed up on the cafeteria wall:


With a plaque that reminded everyone of the barcode DEC used to have and that this new barcode, in the spirit of the original one, spells out Nashua Tech Park.




In my travels about the buildings, I found a three ring binder with a Digital logo on it.  I've put some of my Plexxi documents into it.  There's good karma in these buildings.  Maybe the next big thing is coming from this historic location.  You CAN go home again.


Tuesday, September 4, 2012

Browsers, Browsers, Browsers

After several years of working with HTML, CSS and now GWT and Javascript, it has become quite clear that each browser is going to do things slightly different than others.  This just keeps the engineer on their toes; adds some danger to the mix; provides for some fun with borders and gradients and colors and buttons.

Here's some lessons I've learned recently in getting my GWT application to run across Safari, Chrome, Firefox, Internet Explorer and the Webkit mobile phone browsers.

1. Drawing on a canvas.  My application uses a third party javascript drawing package that uses a canvas for drawing elaborate diagrams.  This works great on all my browsers, except Internet Explorer. Nothing is drawn.  Alas, Internet Explorer doesn't have this native canvas built into it and must be given one.  In my main html file the addition of:

       <!--[if IE]><script language="javascript" type="text/javascript" src="excanvas.js"></script><![endif]-->

did the trick.

2. Right click popup menus.  Any right click you do in a browser produces the typical browser popup menu.  The one to View Source, or Open in New Window.  However, what about when I want to implement my own right click popups and put up my own menus.  In my main html file the addition of:


<body oncontextmenu = "return false;">


did the trick here too.  Now only my popup menus show up and nothing else.


3.  Gradients.  Those light to dark or dark to light backgrounds that make your screen really stand out and look slick.  The following displays a white to blue gradient and works on all browsers.


filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFF', endColorstr='#F3F7FB'); /* IE compatible */

background: -webkit-gradient(linear, left top, left bottom, from(#FFFFFF), to(#F3F7FB)); /* Webkit compatible */

background: -moz-linear-gradient(top,  #FFFFFF,  #F3F7FB); /* Firefox compatible */ 

4. Mobile phone.  Any browser based application, like GWT, should also run on all the mobile platform browsers by default.  But what if you application is just too big to fit nicely or to be useable on a mobile platform?  In this case, you should think about presenting the data in a different view on a mobile device as opposed to being on laptop/desktop computer with adequate screen real estate.  Here's two critical things I did to build a mobile version of my GWT app:

 First - how to detect if my application is trying to be run on Android or iPhone?

        // Is this an Android or iPhone device?
        if (Navigator.getUserAgent() != null)
        {
            if (Navigator.getUserAgent().toLowerCase().contains("android") ||
                Navigator.getUserAgent().toLowerCase().contains("iphone"))
            {
                mobileDevice = true;
            }
        }

Second - how to scale my view to fill the screen on the detect smartphone?

<meta name="viewport" content="width=device-width,initial-scale=1.0" />

Was added to my main html file.  In my case, rather than show my entire GWT application on a mobile device, I chose to show just a list of objects with the ability to touch each one and see more details.  Something simple, something usable, something informative, something that fits on the phone.

As I continue down the path of GWT....I'm sure there will be more browser tweaks needed...keeps me on my toes.

  


Thursday, August 2, 2012

GWT Tricks #3

I love when a simple and elegant solution can be easily integrated into my software.  That doesn't always happen, but I truly believe in the KISS principle, especially when architecting and building complex UI applications that have lots of moving parts.

It was brought to my attention that my empty GWT tables were displaying "1-1 of 0" for my SimplePager display.  This was not my code, but was coming from Googles GWT pager implementation.  A web search showed this was an issue that a lot of folks were complaining about.

To be fair, there's no data in the table, and it clearly says "0" items.   Some web searches showed solutions about overriding GWT code and reimplementing the counter mechanisms.  That led me on my way to a solution.  If my table was empty, I want to display my own text, something like "0 of 0", otherwise, I want to let GWT do the calculation.

The solution was to create my own class that extends the GWT SimplePager and then override the createText() method that displays the counter information:



public class MyPager extends SimplePager
{
    public MyPager(final TextLocation center, final Resources pagerResources, final boolean showFastForwardButton,
                       final int fastForwardRows, final boolean showLastPageButton)
    {
        super(center, pagerResources, showFastForwardButton, fastForwardRows, showLastPageButton);
    }


    // Bug with pager that says 1-1 of 0 when the list is empty. fix it to say 0 of 0.
    @Override
    protected String createText()
    {
        final HasRows display = getDisplay();
        final int dataSize = display.getRowCount();

        if (dataSize == 0)
        {
            return "0 of 0";
        }
        else
        {
            return super.createText();
        }
    }
}

Then just use this new pager for my table:

MyPager pager = new MyPager(SimplePager.TextLocation.CENTER, pagerResources, false, 0, true);


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....

Thursday, August 18, 2011

Internationalization/Localization From the Start

The title says it all. "...From the Start". Don't wait until someone wants to know if your application works with a foreign language to do the work. Retrofitting and removing strings etc. will drive you nuts and will be very unproductive. Instead, put the processes in place at the start so that your answer to their question is "Yes, of course, always has...". Here's some gory details on how, and how nice GWT is in doing the hard work for you:


Determining Locale


Before any of the following code examples will take affect, the system must know what locale it should be running against. This is done by adding the languages you support in your gwt.xml file. For example, to support English add:

<extend-property name="locale" values="en"/>


To add support for another language, say Spanish, add:


<extend-property name="locale” values="es”/>



To include the internationalization code into our Gwt application, we must add:
<inherits name="com.google.gwt.i18n.I18N”/> to our gwt.xml file.


The system will look at the locale running locally on the machine running our application and will tie that to the locale property. If the system sees “es” as the locale, then the application will automatically pick up the Spanish files. If we had created OurStrings.properties and OurStrings_es.properties, then the first file is used by default and the second is used if the locale matches “es”.





Internationalization


To implement an international scheme, we will use static string substitution to make the coding easier and to make the compiled javascript smaller and quicker. The process is as follows:


1. Create a properties file - AppMessages.properties, in the main client folder. This file has ids to strings such as

fileMenu = File

editMenu = Edit

helpMenu = help


2. Create a java interface class of the same naming - AppMessages.java in the main client folder. This file implements the properties file strings:


public interface AppMessages extends Messages
{
String fileMenu();

String editMenu();

String helpMenu();

}

there must be a method for each entry in the properties file.


3. In the main class that runs at startup, in the onModuleLoad() method, construct the class as:


AppMessage msgs = (AppMessages) GWT.create(AppMessages.class));


4. Now you can use the msgs class to find strings such as:


msgs.fileMenu(); which will return “File”.

msgs.editMenu(); which will return "Edit" and so on.



To pass parameters on strings, the properties file would have:
hello = hello {0}


The interface would be:
String hello(String who);


The call would be:
msgs.hello(“Eric”); which will return “hello Eric”.




Localization


Localization deals with the display of dates, times and numbers. Dates displayed in English using month/day/year are displayed differently in other countries, sometimes like day/month/year. So, 5/24/2001 in the US would be displayed as 24/5/2001 in England. Times should be displayed according to the timezone and numbers displayed according to the country formatting where decimal points and comma’s are sometimes intermixed. Gwt has automatic classes built in to support localization. Yes automatic. Based on the locale for the application, the dates, times, currencies will be translated for you:


Data today = new Date();
Wednesday Mar 23 12:11:44 UYT 2011


DateTimeFormat.getFullDateFormat().format(today);
Wednesday, March 23, 2011


DateTimeFormat.getFullTimeFormat().format(today);
12:11:44 PM Etc/GMT+3


There is also Long, Medium and Short formats as well.
DateTimeFormat.getShortDateFormat().format(today);
3/23/11
DataTimeFormat.getShortTimeFormat().format(today);
12:11 PM


For numeric displays, similar builtin Gwt classes are available:
double number = 22919.60;


NumberFormat.getDecimalFormat().format(number);
22,919.6


NumberFormat.getPercentFormat().format(number);
2,291,960%


NumberFormat.getCurrencyFormat().format(number);
$22,919.60


GWT does a lot for you here. There's no excuse to not take advantage of this. Yes, the world puts up with English software for sure, but the goodwill you get for having localized and internationalized applications might just get your company a lot more sales.


Monday, July 18, 2011

Everyone on the Bus

When doing UI development, we all know that we have to deal with callbacks. Callbacks when a mouse button is pressed, callbacks when the screen is resized, callbacks when a menu item is selected, callbacks for just about anything that can happen on your screen.

When designing a well structured piece of software, using object oriented techniques, we will end up with a nice hierarchy of classes, each with their own responsibilities and scope. Traditionally, we would build something like a menu class which handles all the menu creation and callbacks. For example, say someone picks the Help menu. This class gets the callback and launches the help system. But lets say that we want to put help buttons all over our application and give the user the option to get help on a variety of things. This would mean that the menu class would have to be passed around to all the other classes so that the various help buttons could trigger different help system displays. Or we could create one big master class that everyone has access to....but this begins to breakdown, means a lot of parameter passing and just starts to become spaghetti code. Not what we want to maintain.

So what is our option? The Event Bus, aka HandlerManager. What does this do you ask?
Quite simply, the event bus lets our client "fire" an event in one piece of code to be caught and handled by any other piece of code that is listening for this specific event.

Let's see some code. First we want to create an event and its handler. Lets use the help example. When fired, we want to create a help event with a string that will represent "what" help data we want to display.

HelpEventHandler.java:

public interface HelpEventHandler extends EventHandler

{
void onSelect(HelpEvent event);
}



HelpEvent.java:

public class HelpEvent extends GwtEvent

{
public static final Type TYPE = new Type();
private final String helpString;

public HelpEvent(final String helpString)
{
this.helpString = helpString;
}

@Override
protected void dispatch(final HelpEventHandler handler)
{
handler.onSelect(this);
}

@Override
public Type getAssociatedType()
{
return TYPE;
}


public String getHelpString()
{
return helpString;
}

}



We now have defined our event and a handler. Now we need someone to listen for this event as follows:

private final HandlerManager  eventBus   = new HandlerManager(null);


eventBus.addHandler(HelpEvent.TYPE, new HelpEventHandler()
{
@Override
public void onSelect(final HelpEvent event)
{
// Someone fired this event, do something with.
new HelpScreen(event.getHelpString()).show();
}
});




Lastly, we need someone to fire this event for the above listener to receive:

private final HandlerManager  eventBus   = new HandlerManager(null);

eventBus.fireEvent(new HelpEvent("my help topic"));


In summary, we built a specific event and handler. This event has a string as the data payload for it, a string that we use to go to a specific help page. This could be an object, data structure or any data that you want the event to get. We then setup a listener to act on this event being fired. Lastly, we fired the event. In practice, you can now implement a single listener and have lots of places in your code "fire" the event. You may have several places in your application where you want to show "help" and can build a single help display class while allowing any of your code to trigger it.

I've used this technique to allow for the editing of my objects from various places in my code. When someone initiates an edit operation, either from a menu pick, a right click, or by selecting on an object, the event is fired and my "edit object" code catches this request and puts up the edit dialog. I can get to this edit dialog from anywhere and never have to change my edit dialog code to do this.

I can now get to the edit dialog from anywhere in my code, just by Getting on the Bus.