Saturday, December 31, 2011

The Challenges of a JavaFX Reboot

In Jonathan Giles's post An FX Experience Retrospective, he starts by looking at the history of JavaFX and focuses on "what has happened in the world of JavaFX" in 2011. I was highly skeptical of JavaFX prior to JavaOne 2010 (see here and here for examples), but started to think more positively about it after the JavaOne 2010 and JavaOne 2011 announcements related to JavaFX. One thing that has been a little tricky about learning JavaFX since JavaOne 2011's big announcements has been knowing for certain whether a particular resource on JavaFX applies to JavaFX 1.x or JavaFX 2.x. Reading the An FX Experience Retrospective post provided a different perspective on the risks and challenges Oracle and the JavaFX team has faced in making this major overhaul.

Giles writes in his post, "Another vivid recollection I have from JavaOne 2010 is the various reactions that people had of this news. It varied from those in shock at losing their favourite language, to those who said it was long overdue and was the right way to proceed with JavaFX." I was in the latter group, welcoming this change and I would have liked to see it happen even sooner. The ability to use JavaFX with standard Java language and APIs was a huge benefit in my opinion and finally gave credence to the pro-JavaFX argument to Java developers that "JavaFX is Java." The JavaOne 2011 announcements of making JavaFX open source and making it part of standard Java SE were likely less controversial for Java developers (who wouldn't want these characteristics?) and are also important to me in my renewed interest in JavaFX.

For developers just learning JavaFX, it can be a bit tricky to know if an online resource is for JavaFX 1.x or 2.x without delving into the article. The changes in JavaFX from 1.x to 2.x are significant enough that I generally don't want to risk confusion by reading JavaFX 1.x resources (though some have found value in reading JavaFX 1.x resources in preparation for using JavaFX 2.0). However, there are some clues that can help make it quicker and easier to identify which version of JavaFX is applicable.

It is most obvious that an article is about JavaFX 2.0 when it explicitly states so. I try to do this with my blog posts on JavaFX 2.0, though I'm sure I occasionally forget to do so. When an article or blog post does not state the version of JavaFX specifically, another good clue is the date of the resource. In general, it is usually safe to assume that anything written about JavaFX before late 2010 is about JavaFX 1.x and it is similarly safe to assume that most things written about JavaFX in 2011 or later are about JavaFX 2.x.

Another clue to watch for is discussion in a resource that includes JavaFX Script or FXML references. The former (JavaFX Script) was exclusive to JavaFX 1.x and the latter (FXML) is exclusive to JavaFX 2.x.

Some really good documentation on JavaFX 2.x has been made available recently. The JavaFX 2.0 documentation states the following about JavaFX 2.0 versus JavaFX 1.3:

JavaFX 2.0 is the latest major update release for JavaFX. Many of the new features introduced in JavaFX 2.0 are incompatible with JavaFX 1.3. If you are developing a new application in JavaFX, it is recommended that you start with JavaFX 2.0.

The JavaFX 2.0 documentation contains many newly written or updated articles and posts on JavaFX 2.0. This set of documentation includes What is JavaFX?, Getting Started with JavaFX, Working with the JavaFX Scene Graph, Introduction to FXML, Getting Started with FXML, and Using JavaFX Charts.

Books on JavaFX provide another perspective on the challenges associated with the major shift in JavaFX's vision. Most JavaFX books that are currently available were written for JavaFX 1.x. berry120 (who has also blogged on JavaFX 2) recently asked, Any decent books on JavaFX 2? As far as I can tell, the only JavaFX 2.x book currently available is Carl Dea's JavaFX 2.0: Introduction by Example (I hope to write a review of this short, recipe-oriented book in the near future). This book has a publication date (2011) and JavaFX 2.0 in its title, making it clear that it's on Java FX 2.0. With books, which typically have longer time between writing and publishing, even early 2011 publications dates might still mean a book on JavaFX 1.x. Another good clue with books is the price of used books in the Amazon Marketplace. Books on old and/or deprecated language versions tend to be very cheap.

Other books on JavaFX 2.0 are likely to come. Pro JavaFXTM 2 Platform A Definitive Guide to Script, Desktop and Mobile RIA with JavaTM Technology has an advertised publication date of 12 February 2012.

Even downloading the appropriate version of JavaFX might be a tad tricky if one doesn't pay attention. As of this writing, the link http://javafx.com/downloads/windows.jsp provides download links for JavaFX 1.x. This is indicated in the next screen snapshot. The correct location for downloading JavaFX 2.x is the the JavaFX Developer Downloads at http://www.oracle.com/technetwork/java/javafx/downloads/index.html. Depending on what one searches for in a search engine such as Google's search engine, either can be the first returned result.

Carefully wading through online resources and selecting books to purchase is tricky for developers because of the major shift in JavaFX's long-term vision. Giles's post provides some insight into the even greater effort required within Oracle and the JavaFX team to make this major shift. As painful as the shift is, I believe this shift in vision coming at the cost of short-term pain provides JavaFX a fighting chance for a prosperous long-term future.

My Most Popular 2011 Blog Posts

In this post, I briefly summarize my "eight" most popular "2011" posts (six actually posted in 2011 and two posted in late 2010). The two common themes of these posts seem to be broad applicability and future focus. I expected a few of these posts to do well and was surprised that some of these did as well as they did (and surprised that some others did not make the list).

8. All I Want for Java 8 Is... (27 April 2011)

The popularity of the post All I Want for Java 8 Is... is probably best explained by its focus on what may come in a future version of Java. Having DZone (a "Big Link"), reddit, and JavaWorld references also certainly helps.

[7.] Ten Tips for Using Java Stack Traces (22 October 2010)

I personally like the post Ten Tips for Using Java Stack Traces because I believe it is one of those posts that can be useful to people who are relatively new to Java and provides fairly comprehensive coverage and tips for these new Java developers in a very specific but common area. When I wrote that more developers should write blog posts, I had blogs like this one in mind.

6. Java State of the Union: One Year Under Oracle (12 February 2011)

This may be the most surprising post (to me) to have fared so well in 2011.

The post Java State of the Union: One Year Under Oracle turned out to be especially interesting to me now from a historical perspective. At the time of that writing, the future of Java was near a low point (perhaps back a little higher than its lowest point thanks to the already announced participation of IBM and Apple in OpenJDK). It's difficult to believe how much things have changed in the same year! At the time of the writing of my sixth most popular post of 2011, the focus was on issues with the Java Community Process (JCP) and talk of forking Java. Oracle, to their credit, seems to have had a handle on what was happening at this time and, by JavaOne 2011, had made some significant changes that changed the overall Java community outlook for the better. 2011 was a great year for Java, but we didn't necessarily have any reason to believe that would be the case in mid-February of this year.

5. JavaOne 2011: The Definitive Set of HotSpot Performance Command-line Options (3 October 2011)

When I registered for the JavaOne 2011 presentation The Definitive Set of HotSpot Performance Command-line Options, I had no idea how popular that session or my coverage of that session would be. I liked the presentation so much that I purchased the book for which he is the lead author: Java Performance (I hope to write a review of it in coming months). I thought everyone only attended presentations on trendy topics at JavaOne, but I learned that many developers share my same interest in getting better at working with Java in core areas such as performance.

4. JDK 7: New Interfaces, Classes, Enums, and Methods (31 March 2011)

The popularity of JDK 7: New Interfaces, Classes, Enums, and Methods is not surprising given the popularity of Java 7 topics in 2011.

3. HTML5 Date Picker (17 January 2011)

The HTML5 Date Picker post enjoyed advantages of being on a trendy topic (HTML5) and being posted early in the year.

[2.] Seven Indispensable NetBeans Java Hints (9 October 2010)

Although written in late 2009, this post on seven indispensable NetBeans Java Hints remained very popular throughout 2011.

1. JDK 7: The New Objects Class (26 March 2011)

My most popular post by far (more than twice as many hits as the #2 post) has been JDK 7: The New Objects Class. I believe that the popularity of this post is best explained by the fact that the Java 7 java.util.Objects class is generally appealing to Java developers, but is a new "feature" of Java 7 that has perhaps not been as covered as much elsewhere as other features of Java 7.

Conclusion

Common themes associated with my most popular posts of 2011 included trendy topics such as Java 7/8 and HTML5, but also included more core coverage of NetBeans, Java performance, and Java stack traces.

Friday, December 30, 2011

Rendering HTML Within JavaFX

JavaFX 2.0 allows for inclusion of HTML code within a JavaFX application using JavaFX 2.0's WebView and WebEngine classes from the javafx.scene.web package. This post looks at a very simple example of how this can be done. Much more sophisticated applications could enjoy more interaction between the included HTML content and the JavaFX application itself.

My simple example makes use of a JavaFX 2.0 Accordion control to present multiple Java-related sites that I frequently browse headlines ob for articles and posts to read. Each titled pane in the accordion features a different one of these web sites. The next code listing contains the entire Java class for this application and comes in at fewer than 100 lines of code including comments and white space.

WebViewExample.java
package dustin.examples;

import com.google.common.collect.ImmutableMap;
import java.util.Map;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Accordion;
import javafx.scene.control.TitledPane;
import javafx.scene.paint.Color;
import javafx.scene.web.WebView;
import javafx.scene.web.WebViewBuilder;
import javafx.stage.Stage;

/**
 * Simple example of using JavaFX 2.0's WebView class.
 * 
 * @author Dustin
 */
public class WebViewExample extends Application
{
   /**
    * Provide an instance of a JavaFX 2.0 Accordion control with each titled
    * pane in the Accordion featuring a title based on a 'key' value in the
    * provided a map and including WebView content of the page referenced by the
    * URL in the 'value' portion of the map.
    * 
    * @param titleToUrl Mapping of page titles to their URLs to be used as
    *    titled pane titles and source of content respectively.
    * @return Accordion control with web page-based titled panes.
    */
   private Accordion prepareAccordion(final Map<String, String> titleToUrl)
   {
      final Accordion accordion = new Accordion();
      for (final Map.Entry<String,String> webMap : titleToUrl.entrySet())
      {
         final TitledPane pane =
            new TitledPane(webMap.getKey(), buildWebView(webMap.getValue()));
         accordion.getPanes().add(pane);
      }
      return accordion;
   }

   /**
    * Build a simple WebView based on the provided URL.
    * 
    * @param url URL from which content will be rendered in the provided WebView.
    * @return WebView whose content is based on web page at provided URL.
    */
   private WebView buildWebView(final String url)
   {
      final WebView webView =
         WebViewBuilder.create().prefHeight(450).prefWidth(1000).build();
      webView.getEngine().load(url);
      return webView;
   }

   /**
    * JavaFX 2.0's Application.start(Stage) method.
    * 
    * @param stage Primary stage.
    * @throws Exception Exception thrown during execution of JavaFX application
    *    stage.
    */
   @Override
   public void start(final Stage stage) throws Exception
   {
      stage.setTitle("JavaFX 2.0 WebView Example: Favorite Java Web Sites");
      final Group rootGroup = new Group();
      final Map<String,String> titleToUrl =
         ImmutableMap.<String,String>builder()
                     .put("Inspired by Actual Events", "http://marxsoftware.blogspot.com/")
                     .put("JavaWorld", "http://javaworld.com/")
                     .put("Java.net", "http://java.net/")
                     .put("Java Lobby", "http://javalobby.com/")
                     .build();
      rootGroup.getChildren().add(prepareAccordion(titleToUrl));
      final Scene scene = new Scene(rootGroup, 1000, 600, Color.WHITE);
      stage.setScene(scene);
      stage.show();
   }

   /**
    * Main function for running this JavaFX example.
    * 
    * @param arguments Command-line arguments: none expected.
    */
   public static void main(final String[] arguments)
   {
      Application.launch(arguments);
   }
}

In many ways, the above application works something like a stripped-down web browser. JavaFX does a lot of heavy lifting in processing the HTML source and presenting it just as a web browser would via WebView and an associated WebEngine. Some screen snapshots are shown next of how this application appears when it is run. The first image shows the application when it's initially loaded and the four screen snapshots following that one represent each of the four titled panes being clicked in the accordion.

The links within the presented HTML content can be clicked and the application supports traversal of links. However, significantly greater interaction between the JavaFX application and the rendered HTML can be accomplished using the methods on WebEngine that support interaction with JavaScript [such as getOnStatusChanged()]. The underlying document can also be accessed via WebEngine's documentProperty() and getDocument() methods.

With the increasing importance of HTML5, it's nice that JavaFX has built-in support for interacting with HTML, JavaScript, and the DOM.

Integrating JavaFX 2.0 with Swing and SWT

One of the improvements in JavaFX with JavaFX 2.0 has been greater ease of interoperability with Swing and SWT. Several online resources document how this is done. These include Integrating JavaFX into Swing Applications and SWT Interop. However, in a nice example of effective class-level Javadoc documentation, the respective JavaFX classes javafx.embed.swing.JFXPanel and javafx.embed.swt.FXCanvas each provide a simple code sample of how to use the class to embed JavaFX into Swing or SWT code. In this post, I build upon the code samples provided in these classes' Javadoc documentation to demonstrate JavaFX integration with Swing and SWT.

Both JFXPanel and FXCanvas allow a JavaFX Scene to be set on their instance. The instance of Scene (based on my Simple JavaFX 2.0 Text Example post) to be be used in my examples in this post are provided by the method shown in the next JavaFX-specific code example.

Method Providing a JavaFX Scene for Integration
package dustin.examples;

import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.effect.*;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;

/**
 * Simple class intended to be used by two examples of integrating JavaFX with
 * Swing and with SWT. Provides single method {@code createScene()} to be used
 * by the classes that are examples of integrating Swing with JavaFX and SWT
 * with JavaFX.
 * 
 * @author Dustin
 */
public class TextIntegrationSceneCreator
{
   /**
    * Provides an instance of Scene with JavaFX text examples.
    * 
    * @return Instance of Scene with text examples.
    */
   public static Scene createTextScene()
   {
      final Group rootGroup = new Group();
      final Scene scene = new Scene(rootGroup, 800, 400, Color.BEIGE);

      final Text text1 = new Text(25, 25, "(2007) JavaFX based on F3");
      text1.setFill(Color.CHOCOLATE);
      text1.setFont(Font.font(java.awt.Font.SERIF, 25));
      rootGroup.getChildren().add(text1);

      final Text text2 = new Text(25, 50, "(2010) JavaFX Script Deprecated");
      text2.setFill(Color.DARKBLUE);
      text2.setFont(Font.font(java.awt.Font.SANS_SERIF, 30));
      rootGroup.getChildren().add(text2);

      final Text text3 = new Text(25, 75, "(2011) JavaFX to be Open Sourced!");
      text3.setFill(Color.TEAL);
      text3.setFont(Font.font(java.awt.Font.MONOSPACED, 35));
      rootGroup.getChildren().add(text3);

      final Text text4 = new Text(25, 125, "(2011) JavaFX to be Standardized");
      text4.setFill(Color.CRIMSON);
      text4.setFont(Font.font(java.awt.Font.DIALOG, 40));
      final Effect glow = new Glow(1.0);
      text4.setEffect(glow);
      rootGroup.getChildren().add(text4);

      final Text text5 = new Text(25, 175, "(Now) Time for JavaFX 2.0!");
      text5.setFill(Color.DARKVIOLET);
      text5.setFont(Font.font(java.awt.Font.SERIF, FontWeight.EXTRA_BOLD, 45));
      final Light.Distant light = new Light.Distant();
      light.setAzimuth(-135.0);
      final Lighting lighting = new Lighting();
      lighting.setLight(light);
      lighting.setSurfaceScale(9.0);
      text5.setEffect(lighting);
      rootGroup.getChildren().add(text5);

      final Text text6 = new Text(25, 225, "JavaFX News at JavaOne!");
      text6.setFill(Color.DARKGREEN);
      text6.setBlendMode(BlendMode.COLOR_BURN);
      text6.setFont(Font.font(java.awt.Font.DIALOG_INPUT, FontWeight.THIN, 45));
      final Reflection reflection = new Reflection();
      reflection.setFraction(1.0);
      text6.setEffect(reflection);
      rootGroup.getChildren().add(text6);

      return scene;      
   }
}

A JavaFX Scene can be integrated into Swing code via the JavaFX class JFXPanel and its setScene(Scene) method. This is demonstrated in the next code listing, which gets the particular Scene instance from the method in the previous code listing.

JavaFX/Swing Integration with JFXPanel
package dustin.examples;

import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

/**
 * Simple class demonstrating interoperability between Swing and JavaFX. This
 * class is adapted from the example provided in the Javadoc documentation for
 * {@code javafx.embed.swing.JFXPanel}.
 */
public class SwingJavaFxInteroperabilityDemo
{
   private static void initAndShowGUI()
   {
      // This method is invoked on Swing thread
      final JFrame frame = new JFrame("JavaFX / Swing Integrated");
      final JFXPanel fxPanel = new JFXPanel();
      frame.add(fxPanel);
      frame.setVisible(true);

      Platform.runLater(new Runnable()
      {
         @Override
         public void run()
         {
            initFX(fxPanel);
         }
      });
   }

   private static void initFX(JFXPanel fxPanel)
   {
      // This method is invoked on JavaFX thread
      final Scene scene = TextIntegrationSceneCreator.createTextScene();
      fxPanel.setScene(scene);
   }

   public static void main(String[] arguments)
   {
      SwingUtilities.invokeLater(new Runnable()
      {
         @Override
         public void run()
         {
            initAndShowGUI();
         }
      });
   }   
}

The output of running this simple Java Swing application with embedded JavaFX Scene is shown next.

Integrating SWT with JavaFX is arguably even easier and is demonstrated in the next code listing. As with the Swing integration example, the main approach is to call FXCanvas's setScene(Scene) method.

JavaFX/SWT Integration with FXCanvas
package dustin.examples;

import javafx.embed.swt.FXCanvas;
import javafx.scene.Scene;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

/**
 * Simple class demonstrating interoperability between SWT and JavaFX. This
 * class is based on the example provided in the Javadoc documentation for
 * {@code javafx.embed.swt.FXCanvas}.
 * 
 * @author Dustin
 */
public class SwtJavaFxInteroperabilityDemo
{
   public static void main(String[] arguments)
   {
      final Display display = new Display();
      final Shell shell = new Shell(display);
      shell.setText("JavaFX / SWT Integration");
      shell.setLayout(new FillLayout());
      final FXCanvas canvas = new FXCanvas(shell, SWT.NONE);
      final Scene scene = TextIntegrationSceneCreator.createTextScene();
      canvas.setScene(scene);
      shell.open();
      while (!shell.isDisposed())
      {
         if (!display.readAndDispatch()) display.sleep();
      }
      display.dispose();
   }   
}

The next screen snapshot shows what this simple SWT application with embedded JavaFX looks like.

The code listings for Swing integration with JavaFX and for SWT integration with JavaFX shown above are only slightly adapted from the Javadoc documentation for the JavaFX classes JFXPanel (Swing) and FXCanvas (SWT). It is nice that these classes provide these examples in their documentation and it is really nice that integration has become so much easier. For more thorough coverage of JavaFX/Swing integration, see Integrating JavaFX into Swing Applications.

Thursday, December 29, 2011

JavaFX 2.0 Bar and Scatter Charts (and JavaFX 2.1 StackedBarCharts)

JavaFX 2.0 provides built-in capabilities for generating charts, a capability found within the javafx.scene.chart package. In this post, I look at creating bar charts and a scatter chart in using JavaFX 2.0. During the course of this post, I use Guava and some Java 7 features along the way.

Before demonstrating the JavaFX 2.0 chart APIs, this first code listing shows the configuration of data to be used in the examples. In a more realistic scenario, I'd get this data from a data store, but in this case I simply include in directly in the source code for convenient access for the example. Although this code is not itself inherently related to the JavaFX 2.0 charting, there are some interesting things about it. The code makes use of Java 7's underscores in numeric literals to make it easier to read the land size and populations of the sample states used in the data. The code listing also uses Guava's ImmutableMap class (covered in a previous post).

Code that Configures the Sample Data
   /** Simple U.S. state representation. */
   private enum State
   {
      ALASKA("Alaska"),
      CALIFORNIA("California"),
      COLORADO("Colorado"),
      NEW_YORK("New York"),
      RHODE_ISLAND("Rhode Island"),
      TEXAS("Texas"),
      WYOMING("Wyoming");

      private String stateName;

      State(final String newStateName)
      {
         this.stateName = newStateName;
      }
   }

   /** Simple Movie representation. */
   private enum Movie
   {
      STAR_WARS("Star Wars"),
      EMPIRE_STRIKES_BACK("The Empire Strikes Back"),
      RAIDERS_OF_THE_LOST_ARK("Raiders of the Lost Ark"),
      INCEPTION("Inception"),
      CHRISTMAS_VACATION("Christmas Vacation"),
      CHRISTMAS_VACATION_2("Christmas Vacation 2"),
      FLETCH("Fletch");

      private String movieName;

      Movie(final String newMovieName)
      {
         this.movieName = newMovieName;
      }
   }

   /** Mapping of state name to area of state measured in kilometers. */
   private final static Map<String, Long> statesLandSizeKm;

   /** Mapping of state name to estimated number of people living in that state. */
   private final static Map<String, Long> statesPopulation;

   /** Normal audience movie ratings on Rotten Tomatoes. */
   private final static Map<String, Double> movieRatingsNormal;

   /** Critics movie ratings on Rotten Tomatoes. */
   private final static Map<String, Double> movieRatingsCritics;

   /** Dustin's movie ratings. */
   private final static Map<String, Double> movieRatingsDustin;

   /** Maximum population to be shown on bar charts of states' populations.  */
   private final static long POPULATION_RANGE_MAXIMUM = 40_000_000L;

   /** Maximum land area (km) to be shown on bar charts of states' land areas. */
   private final static long LAND_AREA_KM_MAXIMUM = 1_800_000L;

   /** Maximum movie rating to be shown on bar charts. */
   private final static double MOVIE_RATING_MAXIMUM = 10.0;

   /** Width of chart. */
   private final static int CHART_WIDTH = 750;

   /** Height of chart. */
   private final static int CHART_HEIGHT = 600;

   /** Width of chart for Movie Ratings. */
   private final static int MOVIE_CHART_WIDTH = CHART_WIDTH + 350;

   /* Initialize final static variables. */
   static
   {
      statesLandSizeKm =
         ImmutableMap.<String, Long>builder()
                     .put(State.ALASKA.stateName, 1_717_854L)
                     .put(State.CALIFORNIA.stateName, 423_970L)
                     .put(State.COLORADO.stateName, 269_601L)
                     .put(State.NEW_YORK.stateName, 141_299L)
                     .put(State.RHODE_ISLAND.stateName, 4_002L)
                     .put(State.TEXAS.stateName, 695_621L)
                     .put(State.WYOMING.stateName, 253_336L)
                     .build();

      statesPopulation =
         ImmutableMap.<String, Long>builder()
                     .put(State.ALASKA.stateName, 722_718L)
                     .put(State.CALIFORNIA.stateName, 37_691_912L)
                     .put(State.COLORADO.stateName, 5_116_769L)
                     .put(State.NEW_YORK.stateName, 19_465_197L)
                     .put(State.RHODE_ISLAND.stateName, 1_051_302L)
                     .put(State.TEXAS.stateName, 25_674_681L)
                     .put(State.WYOMING.stateName, 568_158L)
                     .build();

      movieRatingsNormal =
         ImmutableMap.<String, Double>builder()
                     .put(Movie.CHRISTMAS_VACATION.movieName, 8.3)
                     .put(Movie.CHRISTMAS_VACATION_2.movieName, 1.3)
                     .put(Movie.STAR_WARS.movieName, 9.3)
                     .put(Movie.EMPIRE_STRIKES_BACK.movieName, 9.4)
                     .put(Movie.RAIDERS_OF_THE_LOST_ARK.movieName, 9.3)
                     .put(Movie.INCEPTION.movieName, 9.3)
                     .put(Movie.FLETCH.movieName, 7.8)
                     .build();

      movieRatingsCritics =
         ImmutableMap.<String, Double>builder()
                     .put(Movie.CHRISTMAS_VACATION.movieName, 6.3)
                     .put(Movie.CHRISTMAS_VACATION_2.movieName, 0.0)
                     .put(Movie.STAR_WARS.movieName, 9.4)
                     .put(Movie.EMPIRE_STRIKES_BACK.movieName, 9.7)
                     .put(Movie.RAIDERS_OF_THE_LOST_ARK.movieName, 9.4)
                     .put(Movie.INCEPTION.movieName, 8.6)
                     .put(Movie.FLETCH.movieName, 7.5)
                     .build();
      movieRatingsDustin =
         ImmutableMap.<String, Double>builder()
                     .put(Movie.CHRISTMAS_VACATION.movieName, 7.0)
                     .put(Movie.CHRISTMAS_VACATION_2.movieName, 0.0)
                     .put(Movie.STAR_WARS.movieName, 9.5)
                     .put(Movie.EMPIRE_STRIKES_BACK.movieName, 10.0)
                     .put(Movie.RAIDERS_OF_THE_LOST_ARK.movieName, 10.0)
                     .put(Movie.INCEPTION.movieName, 9.0)
                     .put(Movie.FLETCH.movieName, 9.0)
                     .build();                     
   }

The next code listing demonstrates the boot-strapping of the sample application. This includes the one-line main function that normally kicks off Java applications and the more interesting start(String[]) method that is overridden from the extended Application class. This code listing also makes use of Java 7's switch-on-Strings capability for a quick-and-dirty implementation of command-line argument parsing to run a particular chart generation demonstration. The example demonstrates that command-line arguments passed to Application.launch(String...) are available to the JavaFX application via the Application.getParameters() method that returns an instance of nested Application.Parameters.

Code that Launches JavaFX 2.0 Charting Demonstration Example
   /**
    * Start JavaFX application.
    * 
    * @param stage First stage of JavaFX application.
    * @throws Exception 
    */
   @Override
   public void start(final Stage stage) throws Exception
   {
      final Parameters parameters = getParameters();  // command-line args
      final List<String> args = parameters.getUnnamed();
      final String firstArgument = !args.isEmpty() ? args.get(0) : "1";
      final int chartWidth = !firstArgument.equals("4") ? CHART_WIDTH : MOVIE_CHART_WIDTH;

      stage.setTitle("Building Bar Charts");
      final Group rootGroup = new Group();
      final Scene scene = new Scene(rootGroup, chartWidth, CHART_HEIGHT, Color.WHITE);
      stage.setScene(scene);

      switch (firstArgument)
      {
         case "1" :
            rootGroup.getChildren().add(buildVerticalLandAreaBarChart());
            break;
         case "2" :
            rootGroup.getChildren().add(buildVerticalPopulationBarChart());
            break;
         case "3" :
            rootGroup.getChildren().add(buildHorizontalPopulationBarChart());
            break;
         case "4" :
            rootGroup.getChildren().add(buildVerticalMovieRatingsBarChart());
            break;
         case "5" :
            rootGroup.getChildren().add(buildStatesLandSizePopulationScatterChart());
            break;
         default :
            rootGroup.getChildren().add(buildVerticalLandAreaBarChart());
      }
      stage.show();
   }

   /**
    * Main function for demonstrating JavaFX 2.0 bar chart and scatter chart.
    * 
    * @param arguments Command-line arguments: none expected.
    */
   public static void main(final String[] arguments)
   {
      Application.launch(arguments);
   }

With the data to populate the charts configured and the basic JavaFX application boot-strapping demonstrated, it's time to start looking at use of the actual JavaFX 2.0 chart APIs. As the code above shows, the first option ("1") leads to generation of a vertical bar chart depicting the sample states' relative land areas in kilometers. The methods executed for that example are shown next.

Generating Vertical Bar Chart with States' Land Areas
   /**
    * Build ObservableList of XYChart.Series instances mapping state names to
    * land areas.
    * 
    * @return ObservableList of XYChart.Series instances mapping state names to
    *    land areas.
    */
   public ObservableList<XYChart.Series<String,Long>> buildStatesToLandArea()
   {
      final ObservableList<XYChart.Data<String,Long>> statesToLandArea =
         FXCollections.observableArrayList();
      for (final State state : State.values())
      {
         final XYChart.Data<String,Long> stateAreaData =
            new XYChart.Data<String,Long>(
               state.stateName, statesLandSizeKm.get(state.stateName));
         statesToLandArea.add(stateAreaData);
      }
      final XYChart.Series<String, Long> landSeries =
         new XYChart.Series<String, Long>(statesToLandArea);
      final ObservableList<XYChart.Series<String, Long>> series =
         FXCollections.observableArrayList();
      landSeries.setName("State Land Size (km)");
      series.add(landSeries);
      return series;
   }

   /**
    * Provides a CategoryAxis instantiated with sample states' names.
    *
    * @return CategoryAxis with sample states' names.
    */
   public CategoryAxis buildStatesNamesCategoriesAxis()
   {
      final ObservableList<String> stateNames = FXCollections.observableArrayList();
      stateNames.addAll(
         State.ALASKA.stateName,
         State.CALIFORNIA.stateName,
         State.COLORADO.stateName,
         State.NEW_YORK.stateName,
         State.RHODE_ISLAND.stateName,
         State.TEXAS.stateName,
         State.WYOMING.stateName);
      final CategoryAxis categoryAxis = new CategoryAxis(stateNames);
      categoryAxis.setLabel("State");
      categoryAxis.setMinWidth(CHART_WIDTH);
      return categoryAxis;
   }

   /**
    * Build vertical bar chart comparing land areas of sample states.
    * 
    * @return Vertical bar chart comparing land areas of sample states.
    */
   public XYChart buildVerticalLandAreaBarChart()
   {
      final ValueAxis landAreaAxis = new NumberAxis(0, LAND_AREA_KM_MAXIMUM, 50_000);
      final BarChart landAreaBarChart =
         new BarChart(buildStatesNamesCategoriesAxis(), landAreaAxis, buildStatesToLandArea());
      landAreaBarChart.setMinWidth(CHART_WIDTH);
      landAreaBarChart.setMinHeight(CHART_HEIGHT);
      landAreaBarChart.setTitle("Land Area (in km) of Select U.S. States");
      return landAreaBarChart;
   }

The above snippet of code shows the three methods I used to generate a bar chart. The method at the bottom, buildVerticalLandAreaBarChart(), instantiates a NumberAxis for the chart's y-axis and uses that implementation of ValueAxis in instantiating a BarChart. The BarChart instantiation invokes the other two methods in the code snippet to create the x-axis with states' names and to prepare the data in ObservableList<XYChart.Series<String,Long>> format to be used in the chart generation. The generated chart is shown next.

Similar code can lead to a similar chart for depicting populations of the sample states. The code for doing this is shown next and is followed by the screen snapshot of the generated chart.

Generating Vertical Bar Chart with States' Populations
   // method buildStatesNamesCategoriesAxis() was shown in previous code listing

   /**
    * Build one or more series of XYChart Data representing state names as 'x'
    * portion and state populations as 'y' portion. This method is likely to be
    * used in vertical presentations where state names are desired on the x-axis
    * and population numbers are desired on the y-axis.
    * 
    * @return Series of XYChar Data representing state names as 'x' portion and
    *    state populations as 'y' portion.
    */
   public ObservableList<XYChart.Series<String,Long>> buildStatesToPopulation()
   {
      final ObservableList<XYChart.Data<String,Long>> statesToPopulation =
         FXCollections.observableArrayList();
      for (final State state : State.values())
      {
         final XYChart.Data<String,Long> statePopulationData =
            new XYChart.Data<String,Long>(
               state.stateName, statesPopulation.get(state.stateName));
         statesToPopulation.add(statePopulationData);
      }
      final XYChart.Series<String, Long> populationSeries =
         new XYChart.Series<String, Long>(statesToPopulation);
      final ObservableList<XYChart.Series<String, Long>> series =
         FXCollections.observableArrayList();
      populationSeries.setName("State Population");
      series.add(populationSeries);
      return series;
   }

   /**
    * Build vertical bar chart comparing populations of sample states.
    *
    * @return Vertical bar chart comparing populations of sample states.
    */
   public XYChart buildVerticalPopulationBarChart()
   {
      final ValueAxis populationAxis = new NumberAxis(0, POPULATION_RANGE_MAXIMUM, 2_000_000);
      final BarChart populationBarChart =
         new BarChart(buildStatesNamesCategoriesAxis(), populationAxis, buildStatesToPopulation());
      populationBarChart.setMinWidth(CHART_WIDTH);
      populationBarChart.setMinHeight(CHART_HEIGHT);
      populationBarChart.setTitle("Population of Select U.S. States");
      return populationBarChart;
   }

The previous two diagrams were vertical diagrams. The next example uses the same population of the states for its sample data as used in the last example, but depicts it with a horizontal bar chart rather than with the vertical chart. Note that the same method is used for generating the axis with states' names as in the last two examples, but its result is passed in as the second argument to the BarChart constructor rather than as the first argument. This change of order to the BarChart constructor changes the chart from vertical to horizontal. In other words, having a CategoryAxis as the first argument and a ValueAxis as the second argument to the BarChart constructor leads to a vertical chart. Switching the order of those two types of Axis leads to a horizontal chart. I also had to switch the order of the mapping of the data being charted so that the key portion was the population and the value portion was the state names. The code is followed by the output.

Generating Horizontal Bar Chart with States' Populations
   // method buildStatesNamesCategoriesAxis() was shown in previous code listings

   /**
    * Build one or more series of XYChart Data representing population as 'x'
    * portion and state names as 'y' portion. This method is likely to be used
    * in horizontal presentations where state names are desired on the y-axis
    * and population numbers are desired on the x-axis.
    * 
    * @return Series of XYChar Data representing population as 'x' portion and
    *    state names as 'y' portion.
    */
   public ObservableList<XYChart.Series<Long,String>> buildPopulationToStates()
   {
      final ObservableList<XYChart.Data<Long,String>> statesToPopulation =
         FXCollections.observableArrayList();
      for (final State state : State.values())
      {
         final XYChart.Data<Long,String> statePopulationData =
            new XYChart.Data<Long,String>(
               statesPopulation.get(state.stateName), state.stateName);
         statesToPopulation.add(statePopulationData);
      }
      final XYChart.Series<Long, String> populationSeries =
         new XYChart.Series<Long, String>(statesToPopulation);
      final ObservableList<XYChart.Series<Long, String>> series =
         FXCollections.observableArrayList();
      populationSeries.setName("State Population");
      series.add(populationSeries);
      return series;
   }

   /**
    * Build horizontal bar chart comparing populations of sample states.
    * 
    * @return Horizontal bar chart comparing populations of sample states.
    */
   public XYChart buildHorizontalPopulationBarChart()
   {
      final ValueAxis populationAxis = new NumberAxis(0, POPULATION_RANGE_MAXIMUM, 2_000_000);
      final BarChart populationBarChart =
         new BarChart(populationAxis, buildStatesNamesCategoriesAxis(), buildPopulationToStates());
      populationBarChart.setMinWidth(CHART_WIDTH);
      populationBarChart.setTitle("Population of Select U.S. States");
      return populationBarChart;
   }

For all of these examples of generating a bar chart, I've made use of JavaFX's XYChart. It turns out that ScatterChart also extends XYChart, so its use is similar to that of BarChart. The big difference in this case (ScatterChart) is that two values-oriented axes will exist. In other words, instead of using states' names for the x-axis (vertical) or for the y-axis (horizontal), each axis will be based on values (land area for x-axis and population for y-axis). These types of charts are often used to visually determine degree of correlation between the data. The code for generating this and the output it generates are shown next.

Generating Scatter Chart of State Population to State Land Size
   /**
    * Build mapping of land area to population for each state.
    * 
    * @return Mapping of land area to population for each sample state.
    */
   public ObservableList<XYChart.Series<Long,Long>> buildAreaToPopulation()
   {
      final ObservableList<XYChart.Data<Long,Long>> areaToPopulation =
         FXCollections.observableArrayList();
      for (final State state : State.values())
      {
         final XYChart.Data<Long,Long> areaPopulationData =
            new XYChart.Data<Long,Long>(
               statesLandSizeKm.get(state.stateName),
               statesPopulation.get(state.stateName));
         areaToPopulation.add(areaPopulationData);
      }
      final XYChart.Series<Long, Long> areaPopulationSeries =
         new XYChart.Series<Long, Long>(areaToPopulation);
      final ObservableList<XYChart.Series<Long, Long>> series =
         FXCollections.observableArrayList();
      areaPopulationSeries.setName("State Land Area and Population");
      series.add(areaPopulationSeries);
      return series;
   }


   /**
    * Build a Scatter Chart depicting correlation between land area and population
    * for each state.
    * 
    * @return Scatter Chart depicting correlation between land area and population
    *    for each state.
    */
   public XYChart buildStatesLandSizePopulationScatterChart()
   {
      final ValueAxis xAxis = new NumberAxis(0, LAND_AREA_KM_MAXIMUM, 50_000);
      xAxis.setLabel("Land Area (km)");
      final ValueAxis yAxis = new NumberAxis(0, POPULATION_RANGE_MAXIMUM, 2_000_000);
      yAxis.setLabel("Population");
      final ScatterChart xyChart = new ScatterChart(xAxis, yAxis, buildAreaToPopulation());
      xyChart.setMinHeight(CHART_HEIGHT);

      return xyChart;
   }

The scatter charts help to visually determine if there is any correlation between a state's land size and its population. Partially because Alaska and Wyoming are included in the set of sample states, there is not much of a correlation. There is much more that can be done to style the JavaFX Scatter Chart.

It is sometimes useful to see more than one series plotted against the same bar chart. To illustrate multiple series in the same bar chart, I'm going to change the same data being used. Instead of using data on states and their sizes and populations, I'm going to use the data shown in the original code listing related to movie ratings. In particular, there are three series here: critics' ratings, "normal" audience members' ratings, and my own ratings. As with the previous examples, I show the code first (most interesting part is method buildRatingsToMovieTitle()), followed by the output.

Generating Movie Rating Bar Chart with Multiple Series (Multiple Rating Groups)
   /**
    * Build one or more series of XYChart Data representing movie names as 'x'
    * portion and movie ratings as 'y' portion. This method is likely to be
    * used in vertical presentations where movie names are desired on the x-axis
    * and movie ratings are desired on the y-axis. This method illustrates
    * multiple series as ratings for both normal audience members and critics
    * are shown.
    * 
    * @return Series of XYChar Data representing state movie names as 'x' portion
    *    and movie ratings as 'y' portion.
    */
   public ObservableList<XYChart.Series<String,Double>> buildRatingsToMovieTitle()
   {
      final ObservableList<XYChart.Data<String,Double>> normalRatings =
         FXCollections.observableArrayList();
      final ObservableList<XYChart.Data<String,Double>> criticRatings =
         FXCollections.observableArrayList();
      final ObservableList<XYChart.Data<String,Double>> dustinRatings =
         FXCollections.observableArrayList();
      for (final Movie movie : Movie.values())
      {
         final XYChart.Data<String,Double> normalRatingsData =
            new XYChart.Data<String,Double>(
               movie.movieName, movieRatingsNormal.get(movie.movieName));
         normalRatings.add(normalRatingsData);
         final XYChart.Data<String,Double> criticRatingsData =
            new XYChart.Data<String,Double>(
               movie.movieName, movieRatingsCritics.get(movie.movieName));
         criticRatings.add(criticRatingsData);
         final XYChart.Data<String,Double> dustinRatingsData =
            new XYChart.Data<String,Double>(
               movie.movieName, movieRatingsDustin.get(movie.movieName));
         dustinRatings.add(dustinRatingsData);
      }
      final XYChart.Series<String, Double> normalSeries =
         new XYChart.Series<String, Double>(normalRatings);
      normalSeries.setName("Normal Audience");
      final XYChart.Series<String, Double> criticSeries =
         new XYChart.Series<String, Double>(criticRatings);
      criticSeries.setName("Critics");
      final XYChart.Series<String, Double> dustinSeries =
         new XYChart.Series<String, Double>(dustinRatings);
      dustinSeries.setName("Dustin");
      final ObservableList<XYChart.Series<String, Double>> series =
         FXCollections.observableArrayList();
      series.add(normalSeries);
      series.add(criticSeries);
      series.add(dustinSeries);
      return series;
   } 

   /**
    * Build vertical bar chart comparing movie ratings to demonstrate multiple
    * series used in a single chart.
    * 
    * @return Vertical bar chart comparing movie ratings.
    */
   public XYChart buildVerticalMovieRatingsBarChart()
   {
      final ValueAxis ratingAxis = new NumberAxis(0, MOVIE_RATING_MAXIMUM, 1.0);
      final BarChart ratingBarChart =
         new BarChart(buildMovieRatingsAxis(), ratingAxis, buildRatingsToMovieTitle());
      ratingBarChart.setMinWidth(MOVIE_CHART_WIDTH);
      ratingBarChart.setMinHeight(CHART_HEIGHT);
      ratingBarChart.setTitle("Movie Ratings");
      return ratingBarChart;
   }

JavaFX 2.1 beta includes a couple new charts, including the StackedBarChart. The stacked bar chart implies multiple series, so I will adapt the last example to use one of these. The stacked bar chart will show each of the three ratings sources contributing to a single bar per movie rather than three bars per movie as in the last example.

Generating StackedBarChart of Movie Ratings
   /**
    * Build one or more series of XYChart Data representing movie names as 'x'
    * portion and movie ratings as 'y' portion. This method is likely to be
    * used in vertical presentations where movie names are desired on the x-axis
    * and movie ratings are desired on the y-axis. This method illustrates
    * multiple series as ratings for both normal audience members and critics
    * are shown.
    * 
    * @return Series of XYChar Data representing state movie names as 'x' portion
    *    and movie ratings as 'y' portion.
    */
   public ObservableList<XYChart.Series<String,Double>> buildRatingsToMovieTitle()
   {
      final ObservableList<XYChart.Data<String,Double>> normalRatings =
         FXCollections.observableArrayList();
      final ObservableList<XYChart.Data<String,Double>> criticRatings =
         FXCollections.observableArrayList();
      final ObservableList<XYChart.Data<String,Double>> dustinRatings =
         FXCollections.observableArrayList();
      for (final Movie movie : Movie.values())
      {
         final XYChart.Data<String,Double> normalRatingsData =
            new XYChart.Data<String,Double>(
               movie.movieName, movieRatingsNormal.get(movie.movieName));
         normalRatings.add(normalRatingsData);
         final XYChart.Data<String,Double> criticRatingsData =
            new XYChart.Data<String,Double>(
               movie.movieName, movieRatingsCritics.get(movie.movieName));
         criticRatings.add(criticRatingsData);
         final XYChart.Data<String,Double> dustinRatingsData =
            new XYChart.Data<String,Double>(
               movie.movieName, movieRatingsDustin.get(movie.movieName));
         dustinRatings.add(dustinRatingsData);
      }
      final XYChart.Series<String, Double> normalSeries =
         new XYChart.Series<String, Double>(normalRatings);
      normalSeries.setName("Normal Audience");
      final XYChart.Series<String, Double> criticSeries =
         new XYChart.Series<String, Double>(criticRatings);
      criticSeries.setName("Critics");
      final XYChart.Series<String, Double> dustinSeries =
         new XYChart.Series<String, Double>(dustinRatings);
      dustinSeries.setName("Dustin");
      final ObservableList<XYChart.Series<String, Double>> series =
         FXCollections.observableArrayList();
      series.add(normalSeries);
      series.add(criticSeries);
      series.add(dustinSeries);
      return series;
   } 


   /**
    * Build a Stacked Bar Chart depicting total ratings of each movie based on
    * contributions of three ratings groups.
    * 
    * @return Stacked Bar Chart depicting three rating groups' contributions
    *    to overall movie rating.
    */
   public XYChart buildStackedMovieRatingsBarChart()
   {
      final ValueAxis ratingAxis = new NumberAxis(0, MOVIE_RATING_MAXIMUM*3, 2.5);
      final StackedBarChart ratingBarChart =
         new StackedBarChart(buildMovieRatingsAxis(), ratingAxis, buildRatingsToMovieTitle());
      ratingBarChart.setMinWidth(MOVIE_CHART_WIDTH);
      ratingBarChart.setMinHeight(CHART_HEIGHT);
      ratingBarChart.setTitle("Movie Ratings");
      return ratingBarChart;
   }

The stacked bar chart is helpful because it provides a quick view of the overall composite rating of each movie along with how much each reviewer group contributed to that overall rating.

JavaFX 2.0 Charts Documentation

The Using JavaFX Charts tutorial covers code examples and corresponding generated chart images for different types of JavaFX 2.0 charts such as pie chart, line chart, area chart, bubble chart, scatter chart, and bar chart. This tutorial also provides sections on using CSS to style charts and information on preparing chart data and generating custom charts.

Conclusion

This post has demonstrated use of the JavaFX charts package to generate bar charts, scatter charts, and stacked bar charts. When JavaFX is accepted as a standard part of the Java SE SDK, it will bring a standard mechanism for generating charts in Java to the SDK.

Sneaking a Peek at JavaFX 2.1 Beta

It was announced earlier this month that the JavaFX 2.1 Developer Preview Edition (early access) for Windows is available for download (previously available for Mac). In the post JavaFX 2.1 early access for Windows (build 06) now available, Jonathan Giles writes as a feedback comment that this new version of JavaFX includes "new charts and a new ComboBox control." He also points out that "there isn’t a public list of highlights yet." Not being known for my patience, I couldn't resist taking a peek at JavaFX 2.1 to see what nice surprises lie in store.

One quick and dirty method I like for a first cut at looking at changes in APIs is to run my simple Groovy script diffVersionsJavadocs.groovy against two versions of Javadoc. The latest version of this simple script is shown next.

diffVersionsJavadocs.groovy
#!/usr/bin/env groovy
// diffVersionsJavadocs.groovy
//
// This simplistic script compares two versions of online Javadoc documentation
// to identify new or removed constructs from one version to the other.
//
// Example comparing Guava Release 10 to Guava Release 11:
//
// Guava Release 10:
//    http://docs.guava-libraries.googlecode.com/git-history/v10.0.1/javadoc/allclasses-noframe.html
// Guava Release 11:
//    http://docs.guava-libraries.googlecode.com/git/javadoc/allclasses-noframe.html
//
//
// Example comparing JavaFX 2.0 to early access version of JavaFX 2.1 (Windows)
//
// JavaFX 2.0:
//    http://docs.oracle.com/javafx/2.0/api/allclasses-noframe.html
// JavaFX 2.1 (Early Access)
//    file:///C:/javafx-2_1-api/allclasses-noframe.html 

if (args.length < 4)
{
   println "\nUSAGE: diffVersionsJavadocs first_label first_url second_label second_url"
   println "\n\twhere first_label is name of first version"
   println "\t      first_url is URL of Javadoc for first version (usually allclasses-noframe)"
   println "\t      second_label is name of second version"
   println "\t      second_url is URL of Javadoc for second version (usually allclasses-noframe)"
   System.exit(-1)
}
@Grab(group='org.ccil.cowan.tagsoup', module='tagsoup', version='0.9.7')

def firstXml = new XmlParser(new org.ccil.cowan.tagsoup.Parser()).parse(args[1])
def firstUrls = firstXml.'**'.a.@href
def firstLabel = args[0]

def secondXml = new XmlParser(new org.ccil.cowan.tagsoup.Parser()).parse(args[3])
def secondUrls = secondXml.'**'.a.@href
def secondLabel = args[2]

compareSetsOfStrings(secondUrls, secondLabel, firstUrls, firstLabel)

/**
 * Compare first Collection of Strings to second Collection of Strings by
 * identifying which Strings are in each Collection that are not in the other.
 *
 * @param firstStrings First Collection of Strings to be compared.
 * @param firstLabel Name of first collection of Strings.
 * @param secondStrings Second Collection of Strings to be compared.
 * @param secondLabel Name of second collection of Strings.
 */
def void compareSetsOfStrings(
   Collection<String> firstStrings, String firstLabel,
   Collection<String> secondStrings, String secondLabel)
{
   println "Constructs in ${firstLabel} But Not in ${secondLabel}"
   def firstButNotSecond = firstStrings - secondStrings
   printIndentedStrings(firstButNotSecond)

   println "Constructs in ${secondLabel} But Not in ${firstLabel}"
   def secondButNotFirst = secondStrings - firstStrings
   printIndentedStrings(secondButNotFirst)
}


/**
 * Print the provided Strings one per line indented; prints "None" if the
 * provided List of Strings is empty or null.
 *
 * @param strings The Strings to be printed
 */
def void printIndentedStrings(Collection<String> strings)
{
   if (!strings?.isEmpty())
   {
      new TreeSet(strings).each
      {
         println "\t${it}"
      }
   }
   else
   {
      println "\tNone"
   }   
}

In this case, I was not able to find the JavaFX 2.1 API documentation publicly available online, so I downloaded the Windows Developer Preview and used the local JavaFX 2.1 API documentation that is included in the download to compare with the publicly available JavaFX 2.0 API documentation. I ran the script as shown in the next screen snapshot.

For convenience and "searchability" purposes, I have included the script's output as text next. The top section shows what I was mostly interested (new constructs in JavaFX 2.1), but the lower section is interesting because there are a surprising number of constructs that were in JavaFX 2.0 Javadoc that are no longer (at least as of now) in teh JavaFX 2.1 Javadoc.

  • Constructs in JavaFX 2.1 But Not in JavaFX 2.0
    • javafx/beans/WeakListener.html
    • javafx/collections/ObservableSet.html
    • javafx/collections/SetChangeListener.Change.html
    • javafx/collections/SetChangeListener.html
    • javafx/collections/WeakListChangeListener.html
    • javafx/collections/WeakMapChangeListener.html
    • javafx/collections/WeakSetChangeListener.html
    • javafx/concurrent/WorkerStateEvent.html
    • javafx/scene/ParentDesignInfo.html
    • javafx/scene/chart/StackedAreaChart.html
    • javafx/scene/chart/StackedAreaChartBuilder.html
    • javafx/scene/chart/StackedBarChart.html
    • javafx/scene/chart/StackedBarChartBuilder.html
    • javafx/scene/control/ComboBox.html
    • javafx/scene/control/ComboBoxBase.html
    • javafx/scene/control/ControlDesignInfo.html
    • javafx/scene/control/SplitPaneDesignInfo.html
    • javafx/scene/input/ContextMenuEvent.html
    • javafx/scene/input/MouseDragEvent.html
    • javafx/scene/layout/GridPaneDesignInfo.html
    • javafx/scene/layout/PaneDesignInfo.html
    • javafx/stage/DirectoryChooser.html
    • javafx/stage/DirectoryChooserBuilder.html
  • Constructs in JavaFX 2.0 But Not in JavaFX 2.1
    • javafx/concurrent/ServiceBuilder.html
    • javafx/event/EventBuilder.html
    • javafx/event/EventTypeBuilder.html
    • javafx/scene/chart/AxisBuilder.html
    • javafx/scene/chart/CategoryAxisBuilder.html
    • javafx/scene/chart/NumberAxisBuilder.html
    • javafx/scene/chart/ValueAxisBuilder.html
    • javafx/scene/control/AccordionBuilder.html
    • javafx/scene/control/ButtonBaseBuilder.html
    • javafx/scene/control/ButtonBuilder.html
    • javafx/scene/control/CellBuilder.html
    • javafx/scene/control/CheckBoxBuilder.html
    • javafx/scene/control/CheckMenuItemBuilder.html
    • javafx/scene/control/ChoiceBoxBuilder.html
    • javafx/scene/control/ContextMenuBuilder.html
    • javafx/scene/control/ControlBuilder.html
    • javafx/scene/control/CustomMenuItemBuilder.html
    • javafx/scene/control/HyperlinkBuilder.html
    • javafx/scene/control/IndexRangeBuilder.html
    • javafx/scene/control/IndexedCellBuilder.html
    • javafx/scene/control/LabelBuilder.html
    • javafx/scene/control/LabeledBuilder.html
    • javafx/scene/control/ListCellBuilder.html
    • javafx/scene/control/ListViewBuilder.html
    • javafx/scene/control/MenuBarBuilder.html
    • javafx/scene/control/MenuBuilder.html
    • javafx/scene/control/MenuButtonBuilder.html
    • javafx/scene/control/MenuItemBuilder.html
    • javafx/scene/control/MultipleSelectionModelBuilder.html
    • javafx/scene/control/PasswordFieldBuilder.html
    • javafx/scene/control/PopupControlBuilder.html
    • javafx/scene/control/ProgressBarBuilder.html
    • javafx/scene/control/ProgressIndicatorBuilder.html
    • javafx/scene/control/RadioButtonBuilder.html
    • javafx/scene/control/RadioMenuItemBuilder.html
    • javafx/scene/control/ScrollBarBuilder.html
    • javafx/scene/control/ScrollPaneBuilder.html
    • javafx/scene/control/SeparatorBuilder.html
    • javafx/scene/control/SeparatorMenuItemBuilder.html
    • javafx/scene/control/SliderBuilder.html
    • javafx/scene/control/SplitMenuButtonBuilder.html
    • javafx/scene/control/SplitPaneBuilder.html
    • javafx/scene/control/TabBuilder.html
    • javafx/scene/control/TabPaneBuilder.html
    • javafx/scene/control/TableCellBuilder.html
    • javafx/scene/control/TableColumnBuilder.html
    • javafx/scene/control/TablePositionBuilder.html
    • javafx/scene/control/TableRowBuilder.html
    • javafx/scene/control/TableViewBuilder.html
    • javafx/scene/control/TextAreaBuilder.html
    • javafx/scene/control/TextFieldBuilder.html
    • javafx/scene/control/TextInputControlBuilder.html
    • javafx/scene/control/TitledPaneBuilder.html
    • javafx/scene/control/ToggleButtonBuilder.html
    • javafx/scene/control/ToggleGroupBuilder.html
    • javafx/scene/control/ToolBarBuilder.html
    • javafx/scene/control/TooltipBuilder.html
    • javafx/scene/control/TreeCellBuilder.html
    • javafx/scene/control/TreeItemBuilder.html
    • javafx/scene/control/TreeViewBuilder.html
    • javafx/scene/control/cell/PropertyValueFactoryBuilder.html
    • javafx/util/PairBuilder.html

We can see from the output above that there is, as of now, a new DirectoryChooser, the already-mentioned new ComboBox control, two new chart types (StackedBarChart and StackedAreaChart), and several new collections listeners. The long list of constructs that are no longer part of JavaFX (as of now for JavaFX 2.1) are all, probably not coincidentally, "builders." UPDATE: Jonathan has pointed out the "builders" are actually in JavaFX 2.1 and were only omitted at one time from the JavaFX 2.1 Javadoc documentation. Based on this, I have striked-out that portion of the output above.

The Jonathan Giles post warns that this early access beta release of JavaFX 2.1 should not be used for production systems, but it is interesting to get a glimpse of what is to come. Perhaps as important as the new features and classes themselves is the fact that updates are occurring.

Tuesday, December 27, 2011

Significant Software Development Developments of 2011

As I did in 2007, 2008, 2009, and 2010, I summarize some of the software development events of 2011 that I find most significant. All of the normal caveats still apply: this list is definitely shaped by personal experience, interests, and biases.

10. Functional Language Popularity

I cannot recall a single day in 2011 where I didn't run across a headline touting the virtues of functional programming in general or a functional programming language in particular as I browsed software development headlines. The ability to enjoy advantages of functional programming in the JVM have been one of the touted advantages of Scala (see honorable mention section of this post for more on Scala's big year). Programming languages such as Haskell (or Jaskell on the JVM) and LISP (invented by John McCarthy, who is mentioned in item #9) are obviously known for their Functional nature, but we have seen articles in 2011 about using functional aspects of other languages. These include Functional Programming in JavaScript (25 December 2011), the IBM developerWorks's series Functional thinking: Functional features in Groovy (started 22 November 2011), and Functional Programming in Java (15 December 2011).

The JVM space has seen a lot of recent activity related to functional programming. Besides languages such as Jaskell, Scala, and Clojure, there are also functional programming-oriented frameworks for Java such as Guava, fun4j, lambdaj, op4j, and Commons Functor.

Regarding writing code in functional programming languages, Bruce Eckel writes, "For me, one of the best things about functional programming is the mental discipline that it produces. I find it helps me learn to break problems down into small, testable pieces, and clarifies my analysis. For that reason alone, it is a worthwhile practice."

Functional programming languages have been around for a long time and 2011 was not even the beginning of renewed interest in them. However, 2011 seemed to be the year that FP really has taken off in mainstream software development blogosphere and press.

9. Legends Lost

This year has seen the deaths of multiple prominent technologists. Steve Jobs was probably the most well-known of these, but we also lost Dennis Ritchie and John McCarthy in the same year.

Physical deaths were not the only losses our industry suffered in 2011. In October 2011, Mark Pilgrim removed his considerable online contributions. This was reminiscent of why the lucky stiff's similar removal of his online presence (with considerable Ruby contributions) in 2009.

8. C++: Another 'Dead' Language Makes a Comeback

2011 was a big year for C++. C++11 (AKA C++0x) was approved and published, the first new standardized version since C++03. C++ was back in the news again and seems to be experiencing an invigoration similar to that Java is experiencing. See C++ and Beyond 2011: Herb Sutter - Why C++? for an example of this.

As mentioned in relation to concurrency, Microsoft is making overtures toward renewed interest in C++ with its C++ AMP (Accelerated Massive Parallelism). In addition, the July 2011 edition of MSDN Magazine featured an editorial called Why C++ Still Matters in which the author stated that "one of the things [MSDN readers have] consistently told us is that we need to not treat C++ like the crazy uncle in the attic." Bjarne Stroustrup's FAQ has an interesting answer to the question Is C++ in Decline?:

No, I don't think so. C++ use appears to be declining in some areas and to be on an upswing in others. If I had to guess, I'd suspect a net decrease sometime during 2002-2004 and a net increase in 2005-2007 and again in 2010-2011, but I doubt anyone really knows. Most of the popular measures basically measures noise and ought to report their findings in decibel rather than "popularity." Many of the major uses of C++ are in infrastructure (telecommunications, banking, embedded systems, etc.) where programmers don't go to conferences or describe their code in public. Many of the most interesting and important C++ applications are not noticed, they are not for sale to the public as programming products, and their implementation language is never mentioned. Examples are Google and "800" phone numbers. Had I thought of a "C++ inside" logo in 1985, the programming world might have been different today.

I think much of what Stroustrup says here about C++ and lack of coverage online has become true for general Java as well. It's not as exciting or trendy to write on traditional Java as it is on newer languages, but one should be careful about assuming that percentage of writers on a topic equates to percentage of users. C++ is not dead yet.

7. Java Community: OpenJDK and Java Community Process

2011 continued to be a big year for OpenJDK. In late 2010, IBM joined OpenJDK and Apple joined OpenJDK shortly thereafter. In 2011, Twitter also joined OpenJDK and Apache Harmony retired to the attic.

Other big news in the Java community involved the Java Community Process (JCP). JSR 348 ("Towards a new version of the Java Community Process") is described in the post JCP.next, JSR 348 -- Towards a New Version of the Java Community Process. This post concludes, "The success of the Java community depends upon an open and transparent JCP, so JCP.next is worthy of our praise and attention." The post lists some early actions of JSR 348, including "greater transparency by requiring that all development is done on open mailing lists and issue trackers" and that "recruiting process for Expert Group members will be publicly viewable." The aim is for "a more public, open, accessible and transparent JCP."

As additional evidence of the big year that 2011 was for the Java community, I cite the first-ever Java Community Keynote at JavaOne during JavaOne 2011. To me, the Java community seems more energized and enthusiastic than it has for several years.

6. JavaScript

2011 was a huge year for JavaScript. First, my citing of Dart, CoffeeScript, and Node.js as "honorable mention" developments (later in this post) and my citing of the year's biggest winner as HTML5 are evidence in and of themselves of the influence of JavaScript in 2011. Oracle announced at JavaOne 2011 their intention to provide a new server-side JavaScript implementation (Project Nashorn) to illustrate and test non-Java language JVM support and for a high-quality server-side JavaScript implementation that runs on the JVM. jQuery's success (and its own 2011 growth) is also another example illustrating the rising prominence of JavaScript.

5. The Return to Java and the Return of Java

A significant trend seen in 2011 was the return to Java by several prominent projects. Twitter, for example, joined the Java Community Process, after earlier moving their search architecture from Ruby on Rails to Java/Lucene. Another recent example has been Yammer moving part of their offering from Scala to Java. Other informative posts that provide evidence of resurgent interest in Java include Edd Dumbill's O'Reilly Radar posts in advance of OSCON Java 2011. Oracle Technology Network's Our Most Popular Tech Articles of 2011 is dominated by Java-related articles.

Alex Handy writes about the recent positive direction of Java in his post Look what 2011 washed in: The return of Java. He writes, "After a long hiatus and seemingly endless dithering by Sun, Oracle has officially given Java the kick in the pants it needed. ... Java is no longer standing still. "

Markus Eisele's post Moving Java Forward? A definition. A year in review. summarizes events in the world of Java in 2011. Eisele references the Oracle slogan "Moving Java Forward" and describes this as "probably the sentence of the year 2011." Regarding 2011, Eisele states, "For me personally this was a powerful Java year."

One could argue that, outside of bloggers and consultants, most Java developers never really left Java. Evidence for this argument include Java's consistently high (almost always #1) ranking in the TIOBE Programming Community Index and in programming language ratings such as Top 10 Programming Languages of 2011. Java remains remarkably popular and vibrant for a "dead language."

Java.net editor Kevin Farnham sums up the year 2011 from a Java perspective: "It's generally agreed that 2011 was a great year for Java and languages that run on the JVM."

4. Mobile Devices Remain All the Rage

Mobile device development was high on my list of software development developments last year and it seems to continue to dominate software development news and trends watching. This doesn't mean that mobile development is the most commonly performed development, but simply means it gets the most attention.

Mobile development should become even more significant with the proliferation of mobile devices. The Economist article Not Just Talk states, "Mobile phones are the world’s most widely distributed computers. Even in poor countries about two-thirds of people have access to one."

We don't need any more evidence of mobile development popularity, but it is worth noting that Objective-C's high ranking in the TIOBE Programming Community Index is almost exclusively due to the Apple mobile devices such as iPhone, iPad, and iPod Touch. Mobile devices from a single company have almost single-handedly moved a programming language from obscurity into the top ten.

3. Cloud Computing

I ranked cloud computing high on last year's list as well. It continues to be the most trendy of software development buzzwords, but also boasts real-life advantages for consumers and developers. I believe that there is no silver bullet and cloud computing does not change that belief. However, even without silver bullets, we've made strides in the software development industry with less significant steps forward and cloud computing does seem to provide advantages in select situations. Nothing (including the cloud) can be best for everyone all the time and in all situations, but cloud computing definitely seems to benefit certain people and situations.

A good read regarding state of the cloud in 2011 is 2011: When cloud computing shook the data center. This post highlights progress in 2011 in terms of both private and public clouds. One sentence in this article was of particular interest: "The road to simplicity seems paved with even more complexity."

An argument could be made (and I think Kevin Farnham has made it) that cloud computing received significant press in 2011, but really didn't have any one easily identifiable single major development in 2011. Rather, many smaller developments and intense online conversation on the topic have added up to make it another big year for the cloud.

2. Making Concurrency Easier

A major trend of 2011 appears to be that of making announcements about how various languages intend to make writing highly concurrent applications easier. This is one of the often advertised benefits of Scala and some of the other newer JVM languages. Even the JVM's oldest language, Java itself, is expected to continue to enhance its concurrency support (after major improvements in J2SE 5 and Java SE 7) with lambda expressions in Java 8 (see Kevin Farnham's Java.net editorial The State of Java: Meeting the Multicore Challenge for a nice overview). Microsoft has shown renewed interest in C++ for developing concurrent applications on its platforms. Specifically, Herb Sutter and Daniel Moth have talked about how C++ Accelerated Massive Parallelism (AMP) "introduces a key new language feature to C++ and a minimal STL-like library that enables you to very easily work with large multidimensional arrays to express your data parallel algorithms in a manner that exposes massive parallelism on an accelerator, such as the GPU."

It is not a coincidence that the rising popularity of Scala and of functional programming are happening as there is a greater interest in making concurrency easier. Martin Odersky has presented (at OSCON Java 2011) on why it's so difficult to get concurrency correct with shared state/memory. Bruce Eckel reminds us of the Brian Goetz presentation that provided significant evidence supporting the same proposition. Goetz talked about this and about greater support for this in Java 7 in a January 2011 interview:

Not only do improved libraries provide pre-baked versions of common idioms, but developers can often sidestep the complexity of concurrency by limiting shared mutable state in their programs. If you don't have shared state, you don't have to coordinate access to that state, which is where the trouble comes from. Functional languages are built on this principle, but we don't have to switch languages to get the benefit -- we just have to adopt the orientation that immutable state is better than mutable state, and seek to increase immutability and decrease sharing. In Java SE 7, we’ll be adding a framework for fork-join decomposition, which makes it easier to write algorithms that parallelize automatically across a wide range of hardware configurations.
1. HTML5's Ascendancy Continues

In last year's software development highlights post, I stated, "HTML5 finally seems to be gaining the traction it needs among the major browsers and among web developers and authors to be worth paying attention to." Many people having been paying attention to HTML5 in 2011 as its popularity has increased rapidly. There are numerous signs of HTML5's taking over the web development ecosystem as it makes inroads into the mobile devices as well. Indeed, one could say that the desire to have a common platform on which to develop applications for the myriad of mobile devices has been the biggest motivator in the successful rise of HTML5.

The victims of HTML5's success are piling up. We learned in the first quarter of 2011 that Google Gears was being eliminated (one of many Google project prunings that occurred in 2011). The announcement of Gears's demise explicitly acknowledged HTML5's role: "we've shifted our effort towards bringing all of the Gears capabilities into web standards like HTML5."

Later in 2011, Adobe announced that it'd no longer develop a Flash Play for mobile devices and quickly followed that announcement up with the announcement that Adobe would attempt to donate Flex (which was already open source, but under Adobe's stewardship) to the Apache Software Foundation. Many Flex developers, of course, hope that this isn't just Adobe's way of using open source as a dumping ground. In explaining the decision regarding Flex in Your Questions About Flex, the Flex blog acknowledges, "In the long-term, we believe HTML5 will be the best technology for enterprise application development." In announcing abandoning of mobile Flash Player in favor of AIR and HTML5, Adobe stated, "HTML5 is now universally supported on major mobile devices, in some cases exclusively. This makes HTML5 the best solution for creating and deploying content in the browser across mobile platforms."

Microsoft provides more examples of the persuasive power of the HTML5 momentum. Early details of Windows 8 and Windows Phone 7 Metro have scared some in the the Silverlight community as evidenced by posts such as Microsoft has Abandoned Silverlight and All Other Plugins in Metro IE, Did Microsoft Just kill Flash, Silverlight?, and Silverlight Developers Have the Smoothest Road to Metro.

HTML5 is still not fully here (Five Things You Can’t Do With HTML5 (yet)), but it already seems to be the victor.

Honorable Mention

These are topics that did not make my Top Ten for 2011, but were very close.

JavaFX Appears Here to Stay

It was at JavaOne 2010 that Oracle announced that JavaFX Script would be deprecated and announced other plans regarding JavaFX 2.0. However, it was in 2011 (again at JavaOne) that Oracle reaffirmed JavaFX's future by announcing plans to open source it and to make it part of standard Java via the Java Community Process. JavaFX 2.0 is now delivered with Oracle's JDK 7 Update 2. Oracle's statements and actions lead me to believe that JavaFX likely has a future after all.

Now that JavaFX SDK is included with Oracle's JDK 7 Update 2 and the JavaFX runtime is included with Oracle's Java 7 Update 2 JRE, JavaFX will be readily available on more machines. JavaFX includes some support for integration with HTML5 and is likely to add additional support for that integration, which should increase the adoption of JavaFX. 2011 may be the biggest year yet for JavaFX. The only reason it did not make my overall top ten is that I believe the interested portion of the development community is still relatively small, but that could change in the near future.

Node.js

The Node.js platform has generally enjoyed a great year in 2011. Although it was created in 2009, significant press attention seems to have been garnered in 2011. Besides numerous blog posts and articles on Node.js in 2011, several books have become available this year. These include Node Web Development (August 2011), Hands-On Node.js (May 2011), and The Node Beginning Book (October 2011). Two more books expected in 2012 are Node: Up and Running: Scalable Server-Side Code with JavaScript and Programming Node.js: Build Evented I/O Applications in JavaScript.

Not everyone in enamored with Node.js as shown by posts Node.js is Cancer and a mixed report in Is node.js best for Comet?

Scala

2011 has been a big year for Scala. In May, Greylock Partners (venture capitalists) invested $3 million (U.S.) in newly created Typesafe, the Scala/Akka company founded by Scala creator Martin Odersky and Akka creator Jonas Bonér that same month.

Scala has received considerable press in recent years and this has seemed to escalate in 2011. I often read comments to posts on Java or other JVM languages that have some enthusiastic Scala user pointing out how whatever task discussed in the post would have been easier in Scala. Bruce Eckel wrote Scala: The Static Language that Feels Dynamic in 2011. There has also been some negative press for Scala recently as document in my post Recent Community Conversation on Scala.

It is my belief that the very existence of such discussion and the fact that people actually cared about the discussion together imply that Scala is at a point where it's in the process of moving into the mainstream. Barb Darrow's article on GigaOM (same site that published Why Modern Applications Demand Modern Tools by two authors from Greylock Partners) called Scala sets sights on top-tier status among the Java faithful suggests that the folks at Typesafe feel similarly (and they are much closer to the situation than I am). Darrow's article starts, "To hear Typesafe tell it, the Scala programming language is about to join the ranks of top-tier development tools such as Java, C++, Ruby, and PHP. A new Scala plugin for the Eclipse integrated development environment (IDE) should help pave the way."

Speaking of Scala and Eclipse, it was announced this month that Scala IDE V2.0 has been released. One of the most common complaints about Scala has been lack of tool support, so this should definitely be welcome.

Other new developments for Scala in 2011 include the release of the Second Edition of Programming in Scala (release date listed differently in different locations and ranging from December 2010 to January 2011) and Cay Horstmann's announcement of his forthcoming book Scala for the Impatient (of which Typesafe has offered a free preview).

Scala, as was the case for the past year or two, continues to "just miss" making my top ten software development developments for the year. I believe that 2012 will be a significant year for Scala because my perception of Scala is that it is at an important juncture in terms of adoption. It seems that it is poised to really take off or flatten out in terms of adoption at this point and which it will be may start to become clearer in 2012.

Cloud and Service Outages

There were some large and highly visible outages this year. The normally highly reliable Blogger (my blog's host) was out for about 24 hours and Amazon's EC2 also went down in 2011. See The 10 Biggest Cloud Outages Of 2011 (So Far) for a list of cloud outages in the first half of 2011 alone.

Any architecture or infrastructure relying on a single point of failure is likely to end up suffering for that decision. These stories simply remind us that this applies to cloud as well.

Google Chrome and Firefox

Adoption of Chrome as web browser of choice continues to rise. Chrome 15 has been reported (StatCounter) to be the most popular single web browser (by specific version). It's surprisingly difficult to measure with certainty which browser is most popular because it depends on which site is doing the counting, but Chrome certainly has been catching up with Firefox in terms of adoption.

I looked at the Blogger Stats for my own blog for the week between December 16 and December 23 and the break-out (not version specific) was 39% Firefox, 23% Chrome, and 20% Internet Explorer. A snapshot of containing these statistics and other browsers is shown next.

Chrome's rapid rise in popularity seems to put Firefox at a disadvantage. However, reports of significant payments from Google to Mozilla for Google to be Firefox's default search engine show that Firefox still has life in it. The post Chrome Engineer: Firefox Is A Partner, Not A Competitor references a Google+ post by Chrome team member Peter Kasting in which Kasting explains his perspective on why Google made the nearly $1 billion deal with Firefox:

People never seem to understand why Google builds Chrome no matter how many times I try to pound it into their heads. It's very simple: the primary goal of Chrome is to make the web advance as much and as quickly as possible. That's it. It's completely irrelevant to this goal whether Chrome actually gains tons of users or whether instead the web advances because the other browser vendors step up their game and produce far better browsers. Either way the web gets better. Job done. The end.

Woody Leonhard writes that "Google needs Firefox now more than ever." Leonhard also observes, "The money's in search, not the browser."

Firefox enjoyed its own progress in 2011. The blog post Firefox: 2011 begins, "Firefox helped make the Web more awesome in 2011." It highlights the release of Firefox 4, Firefox for Android, and how Firefox "introduced Do Not Track to the industry." The post also includes the "Firefox: 2011" infographic (shown below with link to original).

Dart

In a move reminiscent of its release of the Go programming language, Google's announcement of the Dart programming language has created significant discussion in 2011. Lars Bak's announcement of Dart calls the language "a class-based optionally typed programming language for building web applications." Bak goes on to state that Dart is intended to be a "structured yet flexible language for web programming." In a separate interview, Bak states that "I think it's an exaggeration" to call Dart "a JavaScript killer." That stated, JavaScript certainly has its warts and Google has the clout to make web technologies successful (but some do fail).

Dart can be either compiled into JavaScript (reminiscent of Google Web Toolkit's Java-to-JavaScript compilation) or can be run in a virtual machine in the web browser. Dart is an open source language and is available at http://www.dartlang.org/.

CoffeeScript

Speaking of compiling into JavaScript, CoffeeScript is described on its main page as a "little language that compiles into JavaScript." That same main page adds, "CoffeeScript is an attempt to expose the good parts of JavaScript in a simple way." A book on this language, CoffeeScript: Accelerated JavaScript Development, was published in 2011.

NoSQL

NoSQL has generated tremendous development buzz in recent years, but Oracle's 2011 entrance into the world of NoSQL makes 2011 especially noteworthy for the movement. The announcement of CouchBase and SQLite collaborating on UnQL (Unstructured Data Query Language) could also lead to increased adoption of NoSQL databases.

Big Data

A post that articulates why 2011 was a Big Year for Big Data better than I could is The Biggest Big Data Stories of 2011. McKinsey Global Institute has called big data "the next frontier for innovation, competition, and productivity."

NetBeans

The NetBeans Team's End of Year Message 2011 reminds us of the major developments of 2011 for the NetBeans IDE. The message states that 2011 "has been a milestone year for NetBeans where we've hit the 1,000,000 active user mark." The message adds, "We've also released NetBeans IDE 7.0 and NetBeans IDE 7.0.1, and underpinned the success of many other projects." The message also states that NetBeans 7.1 (which is currently in Release Candidate 2) is expected to be released in early 2012. One of the major inclusions with NetBeans 7.1 is JavaFX 2.0 support.

Tech Jobs Market Making a Comeback

The availability of technical jobs, including software development positions, appears to be rising in 2011. Dan Tynan writes, "Now might be just the moment" to say to again say to oneself, " I'm glad I chose a career in tech."

Mono

Mono, the "cross platform ... open source implementation of Microsoft's .Net Framework based on the ECMA standards for C# and the Common Language Runtime" had a big year in 2011. The post Mono in 2011 covers the year 2011 for Mono fairly exhaustively and states, "2011 was a year that showed an explosion of applications built with Mono." Among several developments related to Mono, one that stood out to me was the creation of Xamarin by members of the laid-off former AttachMate/Novell Mono team. This is certainly welcome news for an open source project that some feared was doomed at that point. Today, Mono promises the sharing of code "between iOS, Android and Windows Phone 7."

Devops

"Devops" continued to be a much-hyped concept in 2011. I still struggle to understand exactly how this movement has helped me or will help me, but I do understand the issues the movement/effort is intended to address. Wikipedia defines devops as "an emerging set of principles, methods and practices for communication, collaboration and integration between software development (application/software engineering) and IT operations (systems administration/infrastructure) professionals." Neil McAllister has called devops "IT's latest paper tiger."

Interconnectedness

Most of the items cited in my top ten of 2011 list and in the honorable mention section are highly related to at least one other item in the lists and often to multiple items. For example, functional programming, Scala, making concurrency easier, and the loss of John McCarthy are all related. Similarly, JavaScript is related to HTML5, Dart, CoffeeScript, mobile devices, cloud development, and web browsers.

Conclusion

2011 was yet another year that saw significant developments and advances in the software development industry. The lists compiled in this post indicate how broadly spread these advances were, affecting different programming languages, different deployment environments, and different stakeholders. When one considers that this is a list written by a single individual, it quickly becomes apparent that the actual breadth of advancement is much greater than these biased lists.