Tuesday Feb 26, 2013

Managing Multiple Screens in JavaFX. (Part II)

After finishing with my first application (previous blog), I moved to my second talk I was delivering at JavaOne 2012. Now I was looking to build another UI application, for a small screen and constrained devices. I was looking into having multiple screens, but with very few UI components; I just needed to collect data from the web and displayed it. Looking at my previous framework it wasn't a good fit for this new scenario, and of course there isn't a unique solution for all applications. This is what I was trying to achieve:

  • Build an application for a city information app.

  • An application where you can explore the city's places.

  • Or you can check the map for places of interests.

  • Check the weather

  • Or even change the city

I wanted to build a more dynamic application, where screens just slide in and out... from top, bottom, right and left, like the red arrows implies. I decided to use a technique commonly used in game development, where there is a big background image, and we have a view port, like a small window, and it's by moving this window around that we get the illusion of screen changes. Notice that having a wide background picture create a great navigation effect!



Points to consider:

  • For this application I used NetBeans and JavaFX SceneBuilder, which are my favorite tools.

  • A very important consideration, from my point of view, is to have a good long background image. This will give you a nice navigation effect without any extra programming cost. It just looks good.

  • Only one big screen is designed in Scene Builder, one fxml file and one controller class. Very simple!

  • Think out of the box, your application doesn't always have to have conventional buttons, labels and other components. Navigation doesn't need to be in one direction!. If you design your UI interface correctly, the user will intuitively navigate through it without any problem! Nice looking and modern interfaces doesn't mean it will be difficult to use.

  • Customize your application using CSS. This application uses CSS heavily, giving a nice and unique touch.

    An example of the semi-transparent gray Panel areas styling looks like this:

       .my-gradientpane {
         -fx-background-radius: 10;
                radial-gradient(radius 100%,
                radial-gradient(radius 100%,
         -fx-background-insets: 0,1,2;

    Or customizing your ChoiceBox could be something like this:

       .choice-box {
                  radial-gradient(radius 100%,
                  radial-gradient(radius 100%,
           -fx-background-insets: 0 0 -1 0, 0, 1, 2;
           -fx-background-radius: 25, 25, 24;
           -fx-padding: 0.0em 0.5em 0.0em 0.0em;
           -fx-alignment: CENTER;
           -fx-content-display: LEFT;

    You can find more detailed information about CSS here.

  • The viewport in my application was simply a container; in this case a Panel. This panel was smaller than the image in the background, it was just the screen's size. The rest of the screens were just not visible.

  • Moving around screens is easy. All the screens have the same width and height, so only a simple TranslateTransition was required here. A sample of this:

         private void showPlaces(MouseEvent event) {
            moveScreen(0, -MyEmbeddedApp.DEVICE_HEIGHT);
         private void showWeather(MouseEvent event) {
            moveScreen(MyEmbeddedApp.DEVICE_WIDTH, 0);
         private void moveScreen(int toX, int toY) {
            TranslateTransition moveMe = TranslateTransitionBuilder.

    The annotation @FXML in front of the showPlaces and showWeather methods is to be able to bind these methods to the UI components in your fxml code. More information about this can be found here.

This concludes this second part of how to manage applications with multiple screens using JavaFX. As you can see, there isn't a one-size-fits-all solution, but it's definitely a lot of fun when you need to design your UI interfaces. Have fun, design, think out of the box, and make the life of the user a bit easier and more enjoyable.

You can also see a related video I've created on our YouTube Java Channel, so you can see these applications live.

Friday Feb 08, 2013

Managing Multiple Screens in JavaFX. (Part I)

(Versión en Español)

One of the best things about my job is that it give me the opportunity to write code and play with the latest technologies. As a JavaFX developer I've created all sort of demos, and last year I faced an issue many developer might be facing today: How to transition between screens and how to manage the screen's stack? That is the reason why I've decided to write about my experiences with it, and to share with you a small framework I wrote for that.

For JavaOne 2012 I decided to create a Casino demo, and I needed to have multiple screens, one for each game:

Creating the screens was the easiest part: I used NetBeans in conjunction with JavaFX Scene Builder.

From NetBeans you have multiple options:

  • You can create a New Project, and select JavaFX FXML Application. This option will generate a project containing three files: a fxml file, a java controller and a main class. The fxml file is where all your UI components will be define. The java controller class has the fxml elements injections along with some methods used by the UI. Finally, the main class loads the fxml file, and start the execution of your application.

  • Second option is from an existent project. You can right click your project and select Add Empty fxml file. You will be prompted to acknowledge the creation of a controller associated with this new fxml file, which I recommend to do!. Different from the previous option, in this case no main class will be created, and somewhere in your code you are in charge of loading and displaying your fxml elements.

Once you have the initial fxml file, you can edit it using the JavaFX Scene Builder. It's really easy to use, and you can find some tutorials about it here.

Now, things seem to be really easy, right? Well, not quite. As you start creating your screens, you find yourself with a bunch of fxml files and controllers, one per each screen. This seems reasonable, as we don't want to place all the screens in a single fxml file, but how to manage them?

Here are a few things to keep in mind:

  • StackPane seems to be the first option you can thing of, right? Just have all the screens stacked one on top of each other, and the one on top gets displayed. Changing screens will be just switching places in the stack. This is not a very good idea, as we might be encountering some performance issues. The scene graph will be huge, and loaded with a lot of UI components that are not even visible. Keeping your scene graph small is the first trick for a good performance in your JavaFX application.

  • We definitely want to keep separate fxml for each screen, designing and maintaining the screens will be a much easier job.

  • One controller per screen also makes sense. One more time, we want to maintain separate screens elements and behaviors.

  • We need to define clean and easy navigation among the screens.

  • Once again, we need to keep our scene graph small.

Then, what should we do?

  • StackPane still is a great option for the container, we just need to manage it properly. In the proposed framework, we only have one screen stacked at a time. In our design, I opted for a common background, so the transition between screens was really smooth. When we are transitioning to a new screen, I play a couple of animations. As I've mentioned before I just used fade transitions, but you can customize your framework and have any transition you want. The background always stays there, and the first fade transition takes place, fading out the current screen. The framework implements an EventHandler, so we can listen when this fading process ends, as we need to remove the already invisible screen, and show the new one by adding it to the scene graph and playing a fade-in animation. Only one screen is uploaded in the scene graph. This allows us to keep it as light as possible, and we don't have a negative impact in performance. Here are the steps:

    • Display main screen

    • User select a game

    • The current screen starts to fade out. Once it finishes, the old screen gets remove from the scene graph and the new screen start to fade in.

    • Now the new screen is totally visible (opacity 1), and our graph stays light.

    • The StackPane finishes with only one screen in its tree.
    • With this approach, you can define any transition between the screens. You can drop the new screen from the top, or you can slide in the new screen from any side; you can use any animation you can think of.

Now, lets have a look at the code:

  1. First, all the screens need to know about their parent, in our case the main screen, as we need to be able to return to the main menu once we finish playing, perhaps to choose a different game. A common interface will do the trick (ControlledScreen), with a method for parent injection (setScreenParent), so we can initialize each screen's parent.

      public interface ControlledScreen {

         //This method will allow the injection of the Parent ScreenPane
         public void setScreenParent(ScreensController screenPage);

  2. For each screen, we keep a separate fxml file, and a controller java file, as we mentioned at the beginning of the blog. Each controller class should implement the ControlledScreen, so all of them shared the type, and we can set the screen's parent later on.

      public class Screen1Controller implements Initializable,
                                                ControlledScreen {

         ScreensController myController;

         public void initialize(URL url, ResourceBundle rb) {
             // TODO

         public void setScreenParent(ScreensController screenParent){
            myController = screenParent;

         //any required method here

    • Now as each controller class has a reference to the parent screen, you can define methods to perform the correct navigation. For example if you want to go back to main screen from one of the games, you just need to call somewhere the following method.

         private void goToMain(ActionEvent event){

  3. We need a new class (ScreensController) for managing the screens:

    • This class will extend StackPane, as it seems to be a perfect choice for our scenario.

         public class ScreensController extends StackPane {

    • ScreensController will have a HashMap called screens. This collection contains pairs formed by the screen's ID and the node representing the top of the screen's scene graph.

         private HashMap<String, Node> screens = new HashMap<>();

    • This class has methods for adding, loading and setting the screens:

      • addScreen(String id, Node screen) add the pair (id, screen) to the HashMap screens.

           public void addScreen(String name, Node screen) {
               screens.put(name, screen);

      • loadScreen(String id, String resource) This method loads the fxml file specified by resource, and it gets the top Node for the screen. We can also get the controller associated to this screen, which allows us to set the parent for the screen, as all the controllers shared the common type ControlledScreen. Finally the screen is added to the screens hash map. As you can see from the code, the loaded fxml file, doesn't get added to the scene graph, so the loaded screen doesn't get displayed or loaded to the screen.

           public boolean loadScreen(String name, String resource) {
             try {
               FXMLLoader myLoader = new
               Parent loadScreen = (Parent) myLoader.load();
               ControlledScreen myScreenControler =
                      ((ControlledScreen) myLoader.getController());
               addScreen(name, loadScreen);

               return true;
             }catch(Exception e) {
               return false;

      • setScreen(String screenName). This method displays a screen with a given screen name.

        • First the method verifies that the screen has been previously loaded.

        • We check if there is already a screen been displayed, so we need to play the screen transition sequence. If there isn't any screen, we just add it to the graph and perform a nice fade-in animation.

        • If there is a screen already been displayed, we play an animation to fade out the current screen, and we defined an eventHandler to handle execution after this.

        • Once the screen is invisible, we remove it from the graph, and we add the new screen. Again, a nice animation is played to show the new screen.

           public boolean setScreen(final String name) {

             if(screens.get(name) != null) { //screen loaded
               final DoubleProperty opacity = opacityProperty();

               //Is there is more than one screen
                 Timeline fade = new Timeline(
                   new KeyFrame(Duration.ZERO,
                                new KeyValue(opacity,1.0)),
                   new KeyFrame(new Duration(1000),

                       new EventHandler() {

                         public void handle(ActionEvent t) {
                           //remove displayed screen
                           //add new screen
                           getChildren().add(0, screens.get(name));
                           Timeline fadeIn = new Timeline(
                               new KeyFrame(Duration.ZERO,
                                      new KeyValue(opacity, 0.0)),
                               new KeyFrame(new Duration(800),
                                      new KeyValue(opacity, 1.0)));

                       }, new KeyValue(opacity, 0.0)));
               } else {
                 //no one else been displayed, then just show
                 Timeline fadeIn = new Timeline(
                     new KeyFrame(Duration.ZERO,
                                  new KeyValue(opacity, 0.0)),
                     new KeyFrame(new Duration(2500),
                                  new KeyValue(opacity, 1.0)));
               return true;
             } else {
                 System.out.println("screen hasn't been loaded!\n");
                 return false;

    • We also have an unloadScreen(String name) method, that simple removes the screen from our hashmap, and report the status of this operation.

         public boolean unloadScreen(String name) {
           if(screens.remove(name) == null) {
             System.out.println("Screen didn't exist");
             return false;
           } else {
             return true;

  4. Now all we have to do is start using the framework. Here I show a small piece of code where you load the screens, and show the main one.

       public class ScreensFramework extends Application {

         public static final String MAIN_SCREEN = "main";
         public static final String MAIN_SCREEN_FXML = "main.fxml";
         public static final String POKER_SCREEN = "poker";
         public static final String POKER_SCREEN_FXML =
         public static final String ROULETTE_SCREEN = "roulette";
         public static final String ROULETTE_SCREEN_FXML =

         public void start(Stage primaryStage) {

           ScreensController mainContainer = new ScreensController();




           Group root = new Group();
           Scene scene = new Scene(root);

I found this framework very useful for my application, and I hope this will be valuable for you too. You can find a full implementation with three testing screens available following this link.

You can also see a related video I've created on our YouTube Java Channel, so you can see this application live.

Friday Oct 19, 2012

Unleash the Power of JavaFX

It seems that it was just yesterday that we were getting ready for JavaOne 2012.  Now it's over, but it's definitely a great time to go back and watch the sessions you missed, and learn some of the latest news about Java.  

For this JavaOne, I presented two sessions and one HOL, all of them related to JavaFX:

If you couldn't join us for these sessions, just follow the links and you can watch the videos on demand.

For the HOL I've created a repository at GitHub, as many of the attendees wanted to keep the material.   In this repository you can find the lab document, the NetBeans projects for each exercise and it's appropriate solution.

 Hope you enjoy!

I created and presented a HOL called:  Unleash the power of JavaFX.  In this blog entry I would like to provide you 

Friday Jul 20, 2012

JavaFX Deployment News!

One of the issues developers face almost everyday is the proliferation of Java platforms. Questions like: What version of Java should I use? Should I use the latest features? What about companies that are still running old versions of Java? These are common questions among developers, and just determining the Java release to be used could require much thought.

The majority of developers want to go for the latest build, but most of the time their companies are using older releases of the platform, and upgrading is out of question as it might break some of the older applications. Sometimes, developers don’t even have the rights to update the software, preventing them from writing powerful applications using the latest technologies that they desire.

Well, not anymore. With the JavaFX packager your deployment nightmares are gone! The newest packaging tool for JavaFX applications allows you to bundle your application along with its resources into a package that include a private copy of the Java and JavaFX runtimes, together with a native application launcher. This means you won’t have to worry about what is installed on the machine on which your application is going to run; your application’s package includes everything it needs for execution! Because it has its own private copy of Java and JavaFX runtimes, you don’t have to be concerned about breaking other applications, or asking your client to update the system to be able to run your application. Your application is self contained and ready to be used.

The javafxpackager will generate zip files or native packages depending on the operating system on which your application will be running. For example, if you are running on Windows it could generate EXE or MSI files. On MacOS it would generate a DMG file, and on Linux it would generate an RPM file.

JavaFX Packaging Tool

JavaFX 2.2 provides two options to create your bundles: The command line utility tool javafxpackager, and a set of ant tasks ant-javafx.jar

Before we go any further let’s review the build process for JavaFX applications.

JavaFX applications and preloaders consist of source code, stylesheets, and may or may not contain additional resources. Source code must be compiled, and stylesheets can optionally be converted to binary format. The source code, stylesheets, and other resources are combined to create a JAR archive, which can optionally be signed and have a certificate attached. JavaFX applications and preloaders are packaged into separate JAR archives. For web applications, a deployment descriptor (JNLP file) is prepared to produce the final package, consisting of one or more executable JAR files, the deployment descriptor, and a web page with the embedded application or a link to launch a Web Start application.

You have full control of this process through the JavaFX packager tool or the ant task as shown in the following table.

Now that you know how to package your JavaFX application, there is a small option you need to include in order to produce the application native bundles:

This is an example of the ant task including the generation of native bundles:

nativeBundles can have the following values:

  • image: Bundle of the application in an unpacked form. You can zip it or package it for redistribution.
  • installer: prepackaged image
  • all: generate images and installers

Now that you have generated your native packages, you can install and test your application. For example for Mac OS we have the following default installer:

In addition, you can customize the bundles and have something like this:

For the bundle customization you will need to place resources such as icons in the package/<platform>/ folder:

  • package/macosx/Ensemble2.icns
  • package/windows/Ensemble2.icns

You might also include customs scripts to be used to build the packages:

  • package/macosx/Ensemble2-dmg-setup.scpt
  • package/windows/Ensemble2.wsx

The native packaging capabilities described in this article are available in JDK 7u6 and subsequent releases. I hope you’ll try out these capabilities, leveraging them to make it easy for users to deploy your JavaFX applications!


Angela Caicedo


« August 2016