Skip navigation

Recently I have come upon a blog article which discussed why Swing has to be Deprecated.  My understanding of the author's argument was that since Swing looks ugly compared to HTML5 and nobody uses Swing anymore that it should be deprecated in favor of JavaFX.  The theory was that by deprecating Swing and forcing users to upgrade to JavaFX then all Java GUIs will be better with the ideal world of the mobile and desktop app worlds being one in the same.  The author is apparently a professor for programming (assumption at university) and teaches to his students that nobody actually uses Swing in the real world.  (wow)

This discussion is interesting to me because I find myself deploying a strong combination of Swing and JavaFX using the NetBeans Platform. These views are almost all in support of NASA ground system software, typically behind a DMZ’d sub-network but I also build the tools to be deployed to an analyst’s desk. So my interfaces must look good AND be very usable or nobody will use my software. 

Well I have some problems with how this argument is being presented though I understand why the author is arguing.  If you follow the discussion of the article you'll find many people seemed to take exception to the article.  (a few did agree) The above article seemed to be more of a venting session then a carefully planned argument.  However it is a valid point of view and merits debate so allow me to present my antithesis to further the discussion:

1. Swing is Ugly and HTML5 usually looks nice so we need JavaFX to be nice too!

I've seen some FUgly HTML5 sites and some beautiful Swing apps.  Now what?  Oh we're talking about the typical and not the norm?  You mean like all the "Flat UI" HTML5 web pages that have consumed hipster desires lately yet look like a screenshot from Windows 1.0 or the Amiga Workbench?  

image

Hey there's no borders!  This must be that hawt gnew HTML5 stuff the kids are raving about!

The real problem is that a lot of young developers are trying to ram HTML5 web apps into spaces that Native Applications make the most sense. And why? NOT because of Swing… but because the Java alternative to HTML5 (Swing or JavaFX) isn’t compelling to them. They don't care that they must run their scripts out of a browser (This is SOOO much better than compiled on the JVM right?)  They don't care that their performance drops orders of magnitude and that usability drops quickly compared to a custom Native App.  There are only two things they care about:

1. Does my app look shiny? (Way more important than functionality)

2. Is it really easy to make? (And I mean copy paste in text editor and refresh)

Well HTML5 gives them both for simple data entry, bottom rung UI's and NEWSFLASH.... that's all the pointy haired non-tech managers care about either.  Killing Swing and forcing everyone to move to JavaFX does not mitigate either point because a) the current JavaFX shininess is the same as the HTML5 shininess (CSS) and you have to compile JavaFX while you don't compile your HTML5 code.

2. JavaFX is better because it supports CSS

The more I use JavaFX (2.x) to implement certain views of the various data sets the more I like it.  It's nice and smooth and making good looking interfaces is so much easier.  However that’s all it really provides that Java/Swing did not before … an enhanced skin. I could already do everything I can do in JavaFX 2.x in Swing except the CSS styling.  I could always do nice charts, web browsing and media playback using third party free libraries.  With the exception of Java 8′s integration of JavaFX 3D, the only incentive I have to use JavaFX is the code footprint tends to come out simpler for the flashier things.

How many ways are there to pop a message or show a dialog? How many times are you going to want a different looking menu?  Are you more worried about style or getting the damn app out the door so you can get on to solving your problems? So why deprecate Swing when it is such an effective workhorse? Why does Russia still launch the simple but limited Soyuz design after 50 years? Because it works and they have no real incentive to improve. I think that is the crux of the matter.

3. Deprecating Swing will merge the Desktop and Mobile space

False.

What if Swing deprecated tomorrow?  There would be a lot of butt hurt and everyone would be busily porting their applications to the Mobile compliant JavaFX platforms.  Oh wait JavaFX isn't mobile compliant other than vm's and the brave community ports which generally aren't feature complete or stable.  In fact barring some showstopping surprise announcement from Oracle in the next few months before Java 8 GA, JavaFX won't realistically support even Android until Java 9.  See you in a few years.  So why would anyone bother with upgrading from their hypothetically deprecated Swing code to JavaFX?  Well speaking from over a decade of Mission Critical operationally deployed Swing apps... nobody would.  Too much risk and not enough reward.

What to do?

Here is my offered synthesis of ideas.  First off don’t deprecate Swing… give us some better reasons to use JavaFX. Better 3D! Better and Faster Chart Control! Expanded Media support!  Give younger developers a reason to use Java (FX) at all instead of HTML5 which is eating Java’s lunch. Deprecating Swing won’t stop that because JavaFX as is just isn’t that compelling, and I’m a strong advocate of JavaFX.

In any tactical business decision you need to chose your value proposition.  HTML5 chose Easy and Shiny and naturally forsakes performance and significant customization.  Swing chose Easy and Performance but forsakes Shiny.  JavaFX so far has choosen... Shiny and Easy and Performance??... but it isn't shinier than HTML5 and it isn't easier than HTML5.  It really faster than Swing (excluding JFX8 3D) and only marginally easier.  To make the JavaFX decision more compelling the framework must focus on performance and ease of development. 

For a real-world use case that may sound familiar to some... when sitting down over two years ago to design the software architecture for the NASA GEONS ground system software I reviewed the various Java application development vectors.  I had developed Defense, Commercial, Embedded and Manufacturing applications in Java using Swing, SWT, Eclipse RCP, Web Start and Applet technologies so I had a great cross-section of experience.  I chose the NetBeans Platform, a Swing based plugin framework.  I considered JavaFX but it was too immature at the time. The Swing based NetBeans Platform offered me rapid development of Enterprise features without sacrificing usability or performance.  The extra eye candy that JavaFX offers was a much lower priority.  As a result my development team saved over a third of the estimated development costs which was passed directly to our NASA mission.

Before this becomes a NetBeans Platform commercial I have a point:  If you kill Swing now by deprecating it you lose out on great mature technologies such as the NetBeans Platform with no truly mature replacement on the near horizon.  (Though there are brave developers trying...)  

Developers are creative but lazy, younger developers more so.  If better more feature rich controls are provided, new development will naturally move from Swing to JavaFX and hopefully from Web/HTML5 back to Java. 

In the previous post in this mini-series regarding the work I do on NASA Ground Systems, I showed some screenshots demonstrating data visualization.  The basic tech stack involves combining the NetBeans Platform with custom JavaFX views. This pattern provides some very useful "At-a-Glance" (AoG) displays associated with daily data product generation.

AoG is typically appropriate, especially when in operations where the daily procedures are mostly concerned with a confirmation type validation.  However something more interactive is needed by analysts who's weekly job is to drill down into the data products to explain phenomenons and make forward predictions.  Again a combination of the NetBeans Platform and JavaFX supports this nicely.

For example custom State Vector data arrives daily from upstream data servers to the Mission Operations Control Room. The below image demonstrates the NetBeans Platform providing an encapsulated daily product view (aka product file). 

image

Positional State Vector

The JavaFX scene has a customized Checkbox ListView which updates the scene's scatterplot automatically when checked.  Just check the box of the data item you want and it automagically adds the data series to the scatter plot.

image

Velocity State Vector

It's valuable for both operators and analysts to compare and contrast different data vectors together.

image

Complete State Vector Together

However this is problematic due to axis scale.  So the analyst needs the ability to drill down.  Sure no problem, JavaFX makes adding custom action handlers a breeze.  Here JavaFX allows me to add various Mouse event handlers such as pressed, click, drag etc on ANYTHING including the chart or axes:

image

Zooming In

A simple combo of event handlers for OnPressed and OnDrag allow us to simulate a "brushing" of the chart. Simply tie some animation or visual, in this case a simple Rectangle object, to the event handler and your user will be happy.

image

Better but let's go deeper!  Drill Baby Drill!

image

Detailed zooming

Which takes us down to the heart of the matter.  So the analyst might see the intersection point in time and say:

image

Hey... what's that?

And then hover over one of the data points at the intersection, leveraging the JavaFX support for mouse hover events on everything, even Chart Nodes, and say:

image

Hey... Take me there!

At which the JavaFX Data Node click handler hands some info to the NetBeans Platform.  Now the NetBeans Platform takes care of everything nicely switching the TopComponent view from the JavaFX scene to the raw data view.  It even automatically jumps the cursor to the exact data row and highlights it for you!

image

NetBeans Platform ties it all together!

So you need to build a visualization of data that must loaded and interface dynamically.  Good looks are important so you chose JavaFX but you are starting from an existing Swing based application.  No problem right?  But what if you have a lot of data to load into your Scene? How do you maintain a positive User Experience?

Maybe you are using the NetBeans Platform because... well.. it's pretty awesome.  Operating your application is very responsive up until the point at which you parse and display the data, but then there is a slight wait or even hang while the JavaFX scene is constructed.  The end visual is great but the user experience is tainted by a multi-second wait. 

This can be dealt with, you just need to visually acknowledge the user with some sort of animation to let him know... "Hey I'm still here don't worry!"  No problem.  The following pattern is how you can easily accomplish this either from a straight Swing interop or embedded from a NetBeans Platform application.

To walk through this tutorial, it is assumed you have the following:

  • NetBeans Platform with a multiview TopComponent created
  • The JavaFX runtime added as a wrapped library or additional plugin
  • Some data and a JavaFX scene to display
  • Understanding of the standard JFXPanel interop pattern.

This tutorial was accomplished using NetBeans 7.4 which is just great... go get it!  The version of JavaFX is a 2.x runtime taken from Java 1.7u45.  If you are working from the early releases of JDK 8 then you won't have to worry about wrapping the JavaFX runtime into your NetBeans Platform app... its automagic. 

The assumption taken by this tutorial is that you would like to attach your JavaFX visual to a custom File Type that extends the MultiView element TopComponent API.  This is a very powerful pattern that is typical in RCP development in general and one that I use extensively in all my NASA ground system software.  A problem encountered here is when your file based data sets are relatively large.   Not "Big Data" large... so maybe we'll call it "Medium Data".  The problem is that when you switch from your default 'Source' view to your custom 'Visual' view there is a hang of sorts while your JFXPanel is constructed and loaded.  Starting here in your TopComponent constructor:

public final class SomeBigDataFileVisualElement extends JPanel implements MultiViewElement {

    private SomeBigDataFile obj;
    private JToolBar toolbar = new JToolBar();
    private transient MultiViewElementCallback callback;

    public SomeBigDataFileVisualElement(Lookup lkp) {
        obj = lkp.lookup(SomeBigDataFileDataObject.class);
        assert obj != null;
        initComponents();
        toolbar.setFloatable(false);
        final JFXSomeBigDataFilePanel jfxpanel = new JFXSomeBigDataFilePanel();        
        add(jfxpanel, BorderLayout.CENTER);
    }

You would see a blank TopComponent while waiting for your data to load:

image

Hmm... first impression is that your app is broke.  What if you just need 5 or 6 more seconds?  A lot of naive users will just roll their eyes and harumpf.  Well that's because you put all your JavaFX scene building in  inside of a Platform.runLater() call inside of the JFXPanel constructor.  A typical pattern.  Instead try building your scene in a JavaFX Task thread separate.  Then in your JFXPanel constructor merely build a very light layout with a ProgressIndicator.  Try the following pattern:

    public JFXSomeBigDataPanel() {
        super();
        Platform.setImplicitExit(false);
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                createScene();
                
            }
        });         
    }    
    private void createScene() {
        pane = new BorderPane();
        barPi.setOpacity(0.6);        
        barPi.setVisible(true);
        pane.setTop(barPi);
        scatterPi.setOpacity(0.6);        
        scatterPi.setVisible(true);
        pane.setCenter(scatterPi);
        scene = new Scene(pane);
        setScene(scene);        
    }  

Which intends to load two complicated JavaFX charts (a StackedBarChar and a categorized ScatterPlot.  This will display some nice spinners on the screen. 

image

Notice the little spinner above the big spinner?  Yeah I used a BorderPane... for the example and those are the default resizes that JavaFX does.  Plus trust me they are spinning.  Customize with whatever lightweight graphics you like.

Now move all your heavy lifting into a secondary method that encapsulates the effort within a javafx.concurrent.Task object:

    public void refreshScene(final SomeBigDataFileDataObject fileObj) {
        Task loadTask = new Task() {
            @Override
            protected Object call() throws Exception {
                dobj = fileObj;
                SomeBigDataFile dataFile = new SomeBigDataFile(dobj.getPrimaryFile().getPath(),true);
                barChartXAxis.setCategories(FXCollections.<String>observableArrayList(dataFile.getColumnLabelsContent()));                
                buildStackedBarChart();               
                buildScatterChart();
                Platform.setImplicitExit(false);
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        pane.setTop(stackedBarChart);
                        barPi.setVisible(false);
                        pane.setCenter(scatterChart);
                        scatterPi.setVisible(false);
                    }
                });
             return null;   
            }
        };
        new Thread(loadTask).start();
    }

Here's something that may catch some of you like it did me:  make sure your scene construction is done inside the Task call() method but outside the Platform.runLater() run() method.  Anything inside the Platform.runLater() will still block and will not be done Asynchronously.  The only thing you need inside your runLater() is what MUST be there which is anything that directly changes the screen itself, such as adding your fully constructed JavaFX components to the scene.

Then merely call your new refreshScene() method after you have added your JFXPanel component to your original Swing view.  I merely add this back into the original TopComponent constructor:

    public SomeBigDataFileVisualElement(Lookup lkp) {
        obj = lkp.lookup(SomeBigDataFileDataObject.class);
        assert obj != null;
        initComponents();
        toolbar.setFloatable(false);
        final JFXSomeBigDataFilePanel jfxpanel = new JFXSomeBigDataFilePanel();        
        add(jfxpanel, BorderLayout.CENTER);
       jfxpanel.refreshScene(obj);
    }

And voila you get some spinners display followed by your complete JavaFX scene.  For example straight from my NASA GGSS ground system software:

image

Bonus:

You now have a method that can be called whenever you wish to update your view, like say if your file data is changed either manually or by external process.  Mechanisms are provided by the NetBeans Platform to do this and explaining such is provided by the API and other Tutorials.

As I get closer to deploying our 4th Operational Release of the Duke's Choice award winning GEONSGround System Software I'm combining the NetBeans Platform with custom JavaFX views. This pattern provides some very useful "At-a-Glance" displays associated with daily data product generation. I'm fortunate to have access to quite a bit of complex and timely data much of which is custom to the NASA MMS Mission.

The GGSS is deployed to the MMS Mission Operations Control room, located at the Goddard Space Flight Center in Greenbelt, MD. It supports the overall Flight Dynamics Ground System Software for the MMS mission and is developed by myself as NASA contractor with my company a.i. solutions.  The GGSS is  based on the awesome NetBeans Platform including a.i. solutions internal Ground System and Visualization plugin library 'Polaris'.

image

The above image shows a combination of stacked bar charts and a custom categorized axis scatter plot showing a timeline based PASS or FAIL summary of Telemetry statistics. The visual graphics and layout are all created using JavaFX 2.x.  The entire application layout is within a custom NetBeans Platform.

The actual statistics are generated through daily operational procedure and are collected as file based daily Data Products. (fancy NASA way of saying an ASCII file intended for someone else to consume) The data is generated by leveraging a combination of Java code and a custom Matlab Toolbox written for the mission. It was observed by many that having all this compiled data was not helpful as it was too hard to correlate FAILed overall status times with the individual causation variables.

So as mentioned above integrating JavaFX charts very rapidly provided this needed AoG views.  In the majority of nominal cases a single glance by the user will inform them that everything is a go.  In a failure situation one glance at the custom categories timeline will tell you visually when and why there was a failure:

image

 

This post isn't a discussion of ideal visualization techniques and theory but a practical demonstration using new Java technology.  Combining JavaFX 2.x and the NetBeans Platform has has not only solved these problems but proved to be a very effective pattern to extend.  I will be following this with more similar examples from the same tool.

This is the Voice of Ground Control! NASA Ground Systems and Java Technology

I am Sean Phillips and have been a software engineer for a while now.  For the last few years I've been lucky enough to be a lead developer for some NASA Ground System software that has been deployed directly into the Mission Operations Control room.  (Hence the righteous reference in the title of this blog)

Much of this software is in direct support of the Flight Dynamics subsystems which are focused on Navigation, Orbit Determination and Collision Avoidance.  I'll drop a shameless plug once here in that I've worked as a contractor for a great NASA/USAF company, a.i. solutions

I have used mostly Java, JavaFX and the NetBeans Platform to accomplish this.  Here at this blog  I will be sharing the tips, tricks and lessons learned in deploying Java technology to space based mission critical operations and analysis.  I feel there is a niche here to speak towards in the vast ocean of blogs that everyone is already tired of.  I will be sharing some code snippets that are non-proprietary, cool captured screenshots and occasionally images taken from actual operational software.

http://24.media.tumblr.com/ca6d803cf2bb6dc8ab7da6db18b2dce7/tumblr_mvljyoJcw91swtz6mo1_500.png

Which is the GEONS Ground Support System (GGSS) acting as a backdrop for the Duke.  My software and I were veryVERY fortunate to be nominated and awarded the 2013 Duke's Choice award which is handled through the great people at this website!

http://25.media.tumblr.com/b0a55171f45d81849f0b4d738a302c08/tumblr_muznfo8RzF1swtz6mo1_500.jpg

I pretended to ALMOST drop it as they were handing it to me.  I'm sure they'll call me back next year!

I was then very lucky to be invited to speak during the final JavaOne Community KeyNote address.  I showed a custom 3D video of the MMS mission and walked through the difficulties in supporting it.  I then explained where and how Java, JavaFX and the NetBeans Platform all helped support our Ground System goals.  I then took a few BRIEF moments to demo the actual operational software, demonstrating a strong integration of JavaFX data analysis tools

image

and 3D WorldWind visualizations of orbital position:

http://31.media.tumblr.com/d7b3ca13b99dbb4354eef12ca46f2623/tumblr_mq34on2aSl1swtz6mo1_1280.png

Which in the end is all enabled by the awesome NetBeans Platform!

I felt I did great but if you watch I was surrounded by the 10 year Minecraft modder and James Gosling himself.  Not even NASA missions can compete with that!

Filter Blog