Update your Scene in JavaFX

Usually it is very simple to update your scene in JavaFX. For example if you want to update the X and Y position of your nodes, you can often simply do some stuff like:

node.setLayoutX(100d);
node.setLayoutY(150d);

But this isn’t a good way of doing it. In JavaFX you have to be sure you are in the JavaFX application thread. But how can you know this?

Platform.isApplicationFxThread();

But what if you’re not in that thread?

Platform.runLater(Runnable r);

So each time you would like to update your scene manually, you should check if you’re or not in the FX application thread. So let’s make a really simple helper class:

/**
 * @author Thierry Wasylczenko
 */
public class PlatformHelper {

    public static void run(Runnable treatment) {
        if(treatment == null) throw new IllegalArgumentException("The treatment to perform can not be null");

        if(Platform.isFxApplicationThread()) treatment.run();
        else Platform.runLater(treatment);
    }
}

The method run does the check for you. Finally you can use a lambda expression to execute that code:

final Node node = ... ;
PlatformHelper.run(() -> {
  node.setLayoutX(100d);
  node.setLayoutY(150d);
});

That’s it.

12 Responses to Update your Scene in JavaFX

  1. Pingback: JavaFX links of the week, February 10 // JavaFX News, Demos and Insight // FX Experience

  2. Pingback: Java desktop links of the week, February 10 « Jonathan Giles

  3. Tom says:

    How much different (better?) is this from just always assuming you’re not on the JavaFX thread and always use runLater?

    • Thierry WASYL says:

      I would say to have things done correctly 🙂 I don’t really know if it is much better than always use runLater. I could imagine that it is more efficient by avoiding the JavaFX platform to “queue” that event. I think that if you redraw one thing at a time it should be okay, but if you have a lot of updates to make, I think it would avoid useless treatments for the platform. Maybe Jonathan is much more able to answer to your question 🙂

      • Tom says:

        I have an identical method for Swing, but have been debating (with myself) the value of it for many years.

      • Thierry WASYL says:

        Well, in FX8 you also have SwingUtilities#invokeLater for embedding Swing content in JFX.

      • Tom says:

        Yes. Well, I’m talking pure swing:

        static public void invokeLater(Runnable runnable)
        {
        // if this is the AWT thread, just run it
        if (EventQueue.isDispatchThread() ) runnable.run();
        else
        {
        // this is not the AWT thread, hand it over
        javax.swing.SwingUtilities.invokeLater( runnable );
        }
        }

        Interesting to see how the same things pop up 🙂

      • Thierry WASYL says:

        If it pops up in Swing and JFX, I think it is a nice idea 😀

      • My opinion is that you only want to put things into the runLater queue if you need to. If you are already on the JavaFX application thread then you should not queue the runnable up, and instead perform it immediately. It is generally the advice in UI toolkits to not put too much on the queue as it can result in pulses that are too slow to keep up the expected frame rate.

      • Tom says:

        Interesting arguments. OTOH the method now has a delaying effect on the current pulse, so that could be a poteto potato thingy. Plus it has a duality; changes may be immediate, or they may not. Anyhow, not too relevant I guess.

  4. Montechristos says:

    Is there an addon to a JavaFX application that allows you to find code that does not ‘behave properly’ with respect to Application Thread?

Leave a comment