7 Replies Latest reply on Aug 21, 2012 3:07 AM by jmart

    load an image in background

      Are there any secrets in loading Images in background? I never succeeded in loding an Image like this: Image image1 = new Image("flower.png", true); If I change this example to an URL "http://..." it will work. But I like to load large Imges from disk. image.isError() will always say "false", image.isBackgroundLoading() is "true" and progress is always 0.0.

      Thank you for your help

        • 1. Re: load an image in background
          I use the code below to load images in the background.

          It is a special type of Property that you can bind to. It has an imageUrl property that you set to the Image you would like to load, and after it is loaded it automatically updates itself so your image is shown. If you change it again later, it will load the new image in the background and update itself again.

          Use it like this:
          AsyncImageProperty imageProperty = new AsyncImageProperty();  // create async image loading property
          ImageView view = new ImageView();  // create a View to display images
          view.imageProperty().bind(imageProperty);  // bind to the image property so any changes become visible
          imageProperty.imageHandleProperty().set("/my/image/to/load.png");  // set an image to load
          And the class that I use:
          package hs.mediasystem.beans;
          import javafx.beans.property.ObjectProperty;
          import javafx.beans.property.SimpleObjectProperty;
          import javafx.beans.value.ChangeListener;
          import javafx.beans.value.ObservableValue;
          import javafx.concurrent.Service;
          import javafx.concurrent.Task;
          import javafx.concurrent.Worker.State;
          import javafx.scene.image.Image;
          public class AsyncImageProperty extends SimpleObjectProperty<Image> {
            private final ImageLoadService imageLoadService = new ImageLoadService();
            private final ObjectProperty<String> imageUrl = new SimpleObjectProperty<>();
            public AsyncImageProperty() {
              imageLoadService.stateProperty().addListener(new ChangeListener<State>() {
                public void changed(ObservableValue<? extends State> observable, State oldValue, State value) {
                  if(value == State.SUCCEEDED) {
                  if(value == State.FAILED) {
                  if(value == State.SUCCEEDED || value == State.CANCELLED || value == State.FAILED) {
                    String handle = imageUrl.get();
                    if(handle != null && !handle.equals(imageLoadService.imageUrl)) {
              imageUrl.addListener(new ChangeListener<String>() {
                public void changed(ObservableValue<? extends String> observable, String oldValue, String value) {
                  if(!imageLoadService.isRunning()) {
            public ObjectProperty<String> imageUrlProperty() {
              return imageUrl;
            private void loadImageInBackground(String imageUrl) {
              synchronized(imageLoadService) {
                if(imageUrl != null) {
            private static class ImageLoadService extends Service<Image> {
              private String imageUrl;
              public void setImageUrl(String imageUrl) {
                this.imageUrl = imageUrl;
              protected Task<Image> createTask() {
                final String imageUrl = this.imageUrl;
                return new Task<Image>() {
                  protected Image call() {
                    return new Image(imageUrl);
          The main reason I use this is that it hides the complexity of doing image loading in the background, and that it also works for any type of input (I use InputStreams that come from a Database and these should also be loaded in the background).
          • 2. Re: load an image in background
            Actually I don't know what your problem is. The code below shows that loading an image in the background does work. Just download the image given in the URL inside the code to your local harddrive and adjust the file path accordingly. Don't forget to increase the memory size of the VM because the image is large. When you then start the programm you will first see a black screen and in your console output you will see the progress when it changes. When the loading is complete the image will be shown.

            I should add that the test was done with JavaFX 2.2 build 9 on Windows 7 with JDK 7.
            package jfxfeatures.graphics.image.loading.async;
            import java.io.File;
            import java.net.MalformedURLException;
            import javafx.application.Application;
            import javafx.beans.value.ChangeListener;
            import javafx.beans.value.ObservableValue;
            import javafx.scene.Scene;
            import javafx.scene.image.Image;
            import javafx.scene.image.ImageView;
            import javafx.scene.layout.StackPane;
            import javafx.scene.paint.Color;
            import javafx.stage.Stage;
            public class AsyncImageDemo extends Application {
                 public void start(Stage stage) {
                      String imgURL = null;
                      try {
                           final String remoteURL = "http://www.spacetelescope.org/static/archives/posters/large/earth02.jpg";
                           final String localURL = new File("data/earth02.jpg").toURI().toURL().toExternalForm();
                           final String localFile = "data/earth02.jpg";
                           // Select local or remote image source.
                           imgURL = localFile;
                      } catch (MalformedURLException e1) {
                      StackPane root = new StackPane();
                      Scene scene = new Scene(root, 800, 800);
                      ImageView iv = new ImageView();
                      if (imgURL != null) {
                           Image image = new Image(imgURL, true);
                           image.progressProperty().addListener(new ChangeListener<Number>() {
                                public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                                     System.out.println("Progress: " + newValue);
                 public static void main(String[] args) {
            • 3. Re: load an image in background
              Thank you, The problem was the absolute path. With new File("E:\\P1130414.jpg").toURI().toURL().toExternalForm(); I was able to load the File correct.

              Thank you
              • 4. Re: load an image in background
                If an answer was helpful or correct, you should mark it as such.
                • 5. Re: load an image in background

                  In 2.2 version background load is not working poperly (javafx Image class).

                  My application is working 100% in 2.1.1 version. When I upgrated to 2.2, sometimes load sometimes do not.

                  Please guys see this for community!

                  Thank you.
                  • 6. Re: load an image in background
                    How do you know that the image doesn't load? Do you monitor the image error property?

                    • 7. Re: load an image in background
                      The hardest thing about loading an image from a file is locating the right path. I bet this is a path problem. If your image is in your jar, then you need to treat it as a resource.