My Interview with TechTarget.com on JavaFX, Swing, and the NetBeans Rich Client Platform

I sat down with Jan Stafford of Tech Target at JavaOne in September and discussed our experiences with beginning to migrate to JavaFX from Swing while continuing to use the NetBeans Rich Client Platform (RCP) as the foundation for our application.

I discuss some of the pros of using JavaFX and the NetBeans RCP, such as having the ability to develop very polished looking components using effects such as drop shadows, reflections, and gradients  which may have been do-able in Swing, but were extremely painful and time consuming.  These effects however are baked into the JavaFX framework.

The largest negative at this point has been the learning curve with getting up to speed on Cascading Style Sheets.  Since much of the look and feel of the UI can be applied via CSS, it took a bit of work to learn how to use the style sheets to properly style the UI components.  However, the benefit to using CSS is that the work can be given to a UX/UI developer rather than a Java developer, thus truly decoupling the UI development from the business logic development.

A link to the interview on Tech Target’s website is below.

Interview with Tech Target: JavaFX beats Swing: Changing RIA development platform

techTargetInterview

twitter: @RobTerp

Advertisements

JavaFX is Eye Candy and I Have a Sweet Tooth. (Another Extreme UI Makeover)

In a previous article I showed a redesigned user interface for our Freight Management System (FMS) application using JavaFX as we begin to migrate away from Swing.  We are continuing to design screens for new functionality in FMS, and in this article I will illustrate a makeover I implemented for this new screen using JavaFX, which we had originally had planned to use Swing when the UI was first designed.

The screenshot below shows the original wireframe mock-up of what will be the new “VFC Recovery” screen within our Inbound Planning module of the FMS application.  This module will be used by our warehouse planning personel to display all “Trips” that will be arriving at their terminal.  A trip could be an incoming truck, ship, rail, or flight which has freight destined for the terminal.  On this screen, inbound planners in our warehouses will have the ability to see these incoming trips by arrival date and time.  This is the first layer of nested tables on this tab.  The next layer of tables below the arrival date, is reserved for each trip.  ie in the example below “TOTE*11027” is a ship which is scheduled to arrive on 07-18-12 08:00.  Expanding the trip table, will show the next level of tables, which are the plans for the freight once it arrives at the terminal.  Expanding this table then would show all the shipping containers (called VFCs) that the inbound planners have assigned to their plans, and finally, the VFC rows in this table can be expanded one last time to display all the shipments within the specified container.  As can be seen, the amount of data displayed to the user can get overwhelming pretty quickly.

image
Wireframe mock-up of VFC Recovery screen

The first step in a makeover of the VFC Recovery screen was to try to separate the data in a way that was intuitive for the users to navigate while also giving them the information they need to make their planning decisions.  Below is a picture of what was designed during a whiteboard session.  The inbound trips to the Lynden Transport terminal (Anchorage in this case), would be displayed in a table in the top portion of the screen.  The table would contain a summary of information related to the incoming trip, such as the mode of travel (ie truck, rail, barge, etc), as well as the origin of the trip, and anticipated date/time of the arrival.  The user could select a trip in this table, and the details of the trip would be displayed in a section below the table.  The details section would contain additional information about the trip, as well as contain an “Accordion” component which would have a separate section for each Plan that the inbound planners would be putting together.  The user could then expand one of these sections to view details on all of the containers that had been assigned to a particular plan.

RecoveryDrawingUI
Results of UI design whiteboard session

Once again I used the JavaFX design tool, Scene Builder to construct the new user interface.  In addition, I wanted to make use of the open source JavaFX components that are part of the JFXtras project, which are located here.  Components that are in the JFXtras project unfortunately can’t be added to the component palette in Scene Builder, but it was still easy enough to manually add them to the FXML code that Scene Builder generates, at which point Scene Builder will display them in the application’s UI as if they had been part of the component palette.  (Exactly how I accomplished this could be a future blog post.)

Below is a screenshot of the new UI for the VFC Recovery tab.  I took a bit of inspiration from what I had seen at Grand Central Station in New York, with my goal to make the trip arrivals portion of the UI look something like what you may see in an airport or train station. Two components in the JFXtras library were perfect for this task.  I used the DotMatrixSegment component to create the arrival board’s column headers as well as display the terminal where the trips were arriving at, in this case Anchorage.  I then used the Splitflap component to display the actual summary data about the trip, including arrival date/time, the trip ID, the origin and also the mode.  I found a nice brushed metal background, and used inner and drop shadows to give the board a sense of depth. In the screen shot below, the trip that the user had selected is highlighted by giving the row a green background.

The details section below the arrival board is formatted in a similar fashion to the table found in the previous article’s JavaFX makeover.  I used CSS to create the gradients, rounded corners, borders, background, etc for the section header, accordion component, and data table.

image
JavaFX Mock of VFC Recovery Screen

As mentioned in my previous article, this screen will still reside as a TopComponent within a NetBeans RCP application which will manage our other freight management modules that we will be designing with JavaFX as the UI toolkit.

twitter: @RobTerp

Extreme UI Makeover, JavaFX Edition

We have decided to move forward with JavaFX here at Lynden as we design the next version of our Freight Management System (FMS) application.  The initial version of the application was built on the Netbeans Rich Client Platform and will remain so, but we will be moving from the Swing and Jide (Commercial Swing components) component libraries to JavaFX.  The first application module that we are looking at tackling is called “Inbound Planning”.  This module will be used by warehouse managers at our various terminals to plan how and when to pick up and stage freight that is inbound to their location.

Below is a screenshot of the current FMS application with Planning module that is currently in use.  Warehouse managers run a query for their location and a Jide table displays all shipping containers that are inbound to their location.  Containers are grouped by destination, with each destination being represented by a row in the table.

image

 

Each destination row can then be expanded to reveal a Jide nested table showing all the shipping containers for a particular destination, with each container as a sub row to the destination row.  Finally, each container row can then be expanded to show all the shipments within that specific shipping container, for a total of 3 layers of tables.  In addition, when a user select a shipment, all the details about that shipment are displayed in a separate table in the lower pane of the UI.

image

 

In the next version of the FMS Planning module we will be adding functionality to the application to allow the users to create plans for the incoming containers.  The initial wire frame diagram below was created for the new planning module. The purpose of the new functionality is to allow the manager to see all incoming containers separated by mode of transit, i.e. ship, rail, truck, etc. and then plan for the container’s arrival accordingly by assigning it to a “Unit Plan”.

The top level table is represented by transit mode, which can then be expanded to reveal all the incoming trucks, ships, and trains to the user’s location. For example, the user could expand the “Steamship” row which would show a sub-table showing all scheduled incoming barges to that location.  The manager would like to ensure that all containers are picked up at the shipyard for an incoming voyage and are properly staged at the warehouse for final delivery to the customer. This could be accomplished by expanding the row for a particular voyage which would display sub rows to group the containers by Full-Load, Consolidation, and Transfer shipments.  The user would then expand the appropriate row to see all the containers that fall within one of those three categories.  In order to assign the container to a Unit Plan, the user would click the “Update” button on each row which would display a dialog asking the user which plan to assign the container to, at which point the container would disappear from this screen indicating that the container’s arrival had been planned.

image

 

The feedback that was received regarding this wireframe diagram and corresponding workflow is that this is an overwhelming amount of data to display to the user.  There are 5 levels of nested-tables within this framework and when all are fully expanded it is easy to get lost in the resulting sea of nested rows and columns. 

I was tasked with helping to redesign the UI to make the data a bit more manageable for the users as well as provide an efficient means for them to be able to select the containers they are interested in and assign them to the appropriate Unit Plan as well as give them visibility as to which containers still needed to be assigned to a plan.

The result of a whiteboard session appears below.  Transit modes would be displayed within a row of buttons at the top of the screen which would also show  summary data  regarding the number of shipments within each category.  The user could then select one of the categories and the data would be displayed in a table in the main portion of the UI. For example, if the user selected “Steamship”, the table below would show tabs on its left side, one for each inbound voyage.  When the user selects a voyage, the table would populate with all containers on that voyage that have not yet been assigned to a plan. The tabs would have a progress meter to indicate to the user what percentage of containers on the voyage have been assigned to a plan. An “Accordian” widget would be used to partition the data in the table by container type “Full Load”, “Consolidation” or “Transfer”.  Rather than making the user click a button on each row and display a dialog asking which plan the user wanted to assign the container to, the plans are instead shown in a table on the same screen.  The user could then select one or more container rows and then drag them directly over to the plan they wanted to assign those containers to, at which point the containers would disappear from the table, and the progress meter for the voyage would be updated to reflect the changes.

 

image

 

With the help of the JavaFX design tool, Scene Builder, I was able to design a mock UI of the new Inbound Planning screen. The screenshot below illustrates the “Steamship” mode selected, which changes the button’s color as well as creates a slight glow around the button.The Tote*55433 voyage has been selected and displays all the “Full Load” containers that have not yet been assigned to a plan, but could be dragged over to one of the plans on the right-side table.  The “Sea Land” unit plan is highlighted to illustrated what the table  could look like if the user had dragged any containers over to from the voyage table. (Green and gold are Lynden colors, that which is why the choice of this particular palate).

image

Scene Builder made it extremely easy to add effects such as gradients to the buttons, tabs and unit plan rows to give the components a glossy look.  Also, adding the reflections to the buttons along the top row was a very straightforward task as well as creating the translucent rows of the Unit Plan table.

As previously mentioned, the Inbound Planning module will still reside as a TopComponent within a NetBeans RCP application which will manage our other freight management modules that we will be designing with JavaFX as the UI toolkit as well.

twitter: @RobTerp

Debugging Web Service Issues When Migrating from Glassfish Version 2 to 3.

For the most part our migration of web applications (including web services) from Glassfish version 2 to version 3 has been relatively painless. We did however encounter a strange issue with one of our server apps that has both a web service and an RMI server component. The application has been running without problems on Glassfish 2, but when we attempted to deploy to Glassfish 3 we encountered the error message shown in the screenshot below:

“Error occurred during deployment: Exception while preparing the app: Servlet CarrierBillWS implements 2 web service endpoints but must only implement 1”

image

The initial thought was to go ahead and migrate the application from Java EE 5 to Java EE 6, and hope that corrected the issue. This however did not change anything and we were left with the same error. Googling didn’t produce any useful results so I decided to take a look through some of the glassfish code where the exception was being thrown from.

         WebServicesDescriptor webServices = bundle.getWebServices();
          Collection endpoints =
                 webServices.getEndpointsImplementedBy(webComponentImpl);

         if( endpoints.size() > 1 ) {
             String msg = "Servlet " + getWebComponentLink() +
                     " implements " + endpoints.size() + " web service endpoints " +
                     " but must only implement 1";
             throw new IllegalStateException(msg);
         }

It appears that there could possibly a name collision with classes in the application, which wasn’t being checked for in Glassfish 2. The web service class itself is pretty simple:

@WebService()
public class CarrierBillWS {

    protected CarrierBillWSActor actor;
    protected Logger logger;

    public CarrierBillWS() {
        logger = Logger.getLogger(getClass());
        actor = new CarrierBillWSActor(PropertyManager.getInstance().getProperty(PropKey.UV_SESSION));
    }

    @WebMethod(operationName = "reopenBill")
    public void reopenBill( String dispatchId, String locationCode ) {
        logger.info( "Web service Request received to reopen carrier bill: " + dispatchId + " from location: " + locationCode );
        actor.reopenBill(dispatchId, locationCode);

    }
}

For fun, I commented out the @WebService annotation and deployed the application without any issues, with the obvious result being that there was no CarrierBillWS web service listed in the Glassfish admin console, but I was at least able to deploy. I then did a grep for “CarrierBillWS” and to my surprise found another class with the same name in one of the web service app’s dependencies. This dependency is a .jar file that is shared across multiple applications here at Lynden, including the web service. So, why was there a class with the same name in this library? It was because the library also contained code for a client of this CarrierBill web service which other applications depended on for communicating with the service. The CarrierBillWS application itself depends on this .jar file for other functionality that is shared across multiple apps. When the jar was built, it pulled down the WSDL from the web service and auto generated the client side classes, which included a CarrierBillWS client side class. This .jar was then bundled in the web service’s .war file, and Glassfish was finding both classes and then complaining.

The solution to the problem was pretty simple; override some of the default values of the @WebService annotation, and then rebuild the dependency using a new WSDL.

@WebService(serviceName="CarrierBillWebService", name="CarrierBillWebService")
public class CarrierBillWS {

The new “serviceName” and “name” properties on the WebService annotation will cause the client project to generate code with a class name of CarrierBillWebService rather than CarrierBillWS. When the .jar is built, the Web Service and its client related classes in the dependent jar now have different names and Glassfish v3 loads the application without any issues.

Since there wasn’t much info out there on this particular issue, I’m hoping that this may help someone in the future who encounters a similar problem.

Twitter: @RobTerp

Coping with unreliable wireless network connections between Windows CE and JMS using Apache MINA

Our freight tracking and cross docking system which consists of handheld barcode scanners which are running a C# application on Windows CE (written in-house), needed a reliable way to communicate with each other using our backend ActiveMQ Java Message Service infrastructure.  These devices include Symbol MC9090 handheld scanners, WT4090 wrist mount scanners as well as VC5090 forklift mounted scanners (all pictured below).

MC 9090 Handheld Device

VC 5090 Forklift Mounted Device

WT 4090 Wristmount Device

There were a number of challenges integrating these devices which were running .Net software communicating via a Java messaging server.  The original route we headed down was to use the .Net Messaging Service API (NMS) for ActiveMQ, with the devices communicating directly to the message broker. The NMS libraries are .NET assemblies that provide access to ActiveMQ via the native OpenWire protocol. This approach however proved to be an ineffective solution for the following reasons.

  • We learned that the next release of the .NET Message Service API (NMS) library would be dropping support for Windows CE. So even if we wanted to continue this route we either couldn’t or we’d need to modify the NMS library ourselves to support our CE clients.
  • NMS/OpenWire failover protocol was problematic on Windows CE.  Even though we were only running 1 production messaging broker, we were using the failover protocol on the client since it provided a way for the client to automatically attempt to reconnect to the messaging broker should the connection go down. (This happens frequently on these devices).
  • Unreliable network connections.  To expand on the point above further, devices are constantly taken in and out of truck trailers where the Wi-Fi connections are spotty.  Connections to the messaging system were not always getting properly cleaned up, and as a result, excessive resources would gradually be consumed over time on the broker which caused instability and occasional crashes on the server side.

In light of the above challenges it was decided to develop a proxy server to handle the communication between the CE devices and the messaging broker and act as a buffer for all the frequent disconnects/reconnects that the devices experienced.  We had initially looked at the REST API provided by ActiveMQ, but due to lack of support for durable subscriptions at the time (it may support them now), we ruled that option out.


Apache MINA and the MINA State Machine Libraries

The Apache MINA libraries provide a way to create network applications in an efficient and scalable way. The framework makes use of Java NIO and features an event driven API which allowed for a very elegant design of the proxy server. Even better, the MINA State Machine (which has no official release at this time, but the code can be downloaded and built from the MINA Subversion repository) provided an easy way to manage various states of the messaging clients (ie. Connected, Subscribed, Unsubscribed, etc). An ASCII based protocol was used as the communication medium between the clients and the proxy server.  In this manner, we could also make use of the proxy to connect Java desktop clients since their connection to the messaging system would be somewhat transient (as users stopped and started the application), although not as transient as the device connections in the field.  The ASCII protocol would also allow us to tie in our legacy BASIC applications to the messaging system which are running on the UniVerse database and application platform.  Existing server side Java applications would still be allowed to talk directly with the broker because in theory, their connection to the messaging system should be constant and stable. We are currently hosting the proxy server within our Glassfish3 application server with our other web applications since it provides an easy way to manage the proxy’s lifecycle. The chart below illustrates the current paths the various applications in our system take to access the message server.


Future directions

One obvious weakness with the design that is illustrated above is that of failover support (or lack thereof). Even if we were to run multiple message brokers for fault tolerance, the proxy server itself is still a single point of failure within the system. Support for Java and BASIC clients as previously mentioned will also be at the top of our list of additions to make to our messaging solution.

Twitter: @RobTerp


Freight Management System on NetBeans Rich Client Platform

Lynden is a family of transportation and logistics companies specialized in shipping to Alaska [1] and other locations worldwide. Over land, on the water, in the air – or in any combination – Lynden has been helping customers solve transportation problems for over a century.

The Lynden Freight Management System is a NetBeans Platform application [2] which serves a dual purpose as both a planning and freight tracking tool.

  • The Planning module allows terminal managers to see all freight that is currently inbound to their location as well as freight that is scheduled to depart from their location so they can make the most efficient use of their dock space and resources as possible.
  • The Trace module allows customer service personnel to search for customer account information, view the tracking history of any given freight item in the system as well as display any documents related to the shipment, such as bills of lading or delivery receipts.

NetBeans Platform

Lynden has benefited from the NetBeans Platform as it allows developers to focus on the business logic of our applications rather than the underlying “plumbing”.  We are able to leverage built-in support for event handling, enable/disable functionality on UI controls, dockable windows, and automatic updates for our application with minimal work compared to rolling our own framework.

We chose to go the desktop application route as we have a number of existing desktop applications that this application will need to interface with, as well as a commercial set of rich UI components that we have been using for some time now. For the initial deployment, we will be pushing the application installer out to employees PCs via the Landesk remote desktop administration tool.  Future updates to various modules within the application will be done via the update center functionality built into the NetBeans Platform.

Screenshots