简体   繁体   中英

Progress Bar while downloading image in javafx

Hello Stackoverflowers, I will be short, so my question is : How can i show a progress-bar in my application while my image is being downloaded? I did some research,and i found something about "preloader" and "splach-screen", but we can use these last only before starting my main-application, and about progress bar, i know i have to bind it, but how can i bind it with my image ? I appreciate any kind of help.

this is my code of creating a simple slide show :

@PostConstruct
public void init()
{

    All_photos photos = (All_photos) new parse_object <All_photos> (All_photos.class).ParseUri("https://api.edmunds.com/api/media/v2/styles/"+id+"/photos?api_key=wdxg7wh338vac3359m34qjj6&fmt=json");

    Images = new ArrayList<Image>();

    ArrayList<String> list_href = new SlideShowHelper().get_href(photos);

    for ( String st:list_href)
    {
        System.out.println(st);
        Images.add(new Image("https://media.ed.edmunds-media.com"+st+""));
    }
    }

just to know, that image take a while to be downloaded, it depends on internet connection speed.

This answer answers your question title: "Progress Bar while downloading image in javafx".

The code in your question is a bit unclear, so the answer may or may not answer what you really wish to achieve.

熊

  1. Load the image in the background .
  2. Bind the progress property of the ProgressBar to the progessProperty of the image.

Note: for the sample code and image, the image loads very quickly so you don't actually see the progress bar moving. For a very large image being loaded and a very slow internet connection, you may see the progress bar move as the loading progresses.

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ProgressBar;
import javafx.scene.image.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class ImageLoadProgress extends Application {

    private static final String IMAGE_LOC =
            "http://icons.iconarchive.com/icons/custom-icon-design/flatastic-10/128/Bear-icon.png";

    @Override
    public void start(Stage stage) throws Exception {
        Image image = new Image(IMAGE_LOC, true);
        ProgressBar bar = new ProgressBar();
        bar.progressProperty().bind(image.progressProperty());

        ImageView imageView = new ImageView(image);
        imageView.setFitWidth(128);
        imageView.setFitHeight(128);
        stage.setScene(new Scene(new VBox(5, bar, imageView)));
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Update for additional question

how can i create a task with several images being downloaded and one progress bar ?

Use a DoubleExpression which is maps to the average of the background loading progress of all to the images.

多张图片

import javafx.application.Application;
import javafx.beans.binding.DoubleExpression;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.scene.Scene;
import javafx.scene.control.ProgressBar;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.util.Arrays;
import java.util.stream.Collectors;

public class ImagesLoadProgress extends Application {

    private static final String IMAGE_PATH_PREFIX =
            "http://icons.iconarchive.com/icons/custom-icon-design/flatastic-10/128/";

    private static final String[] IMAGES_FILENAMES = {
            "Bear-icon.png",
            "Bow-icon.png",
            "Sport-american-football-icon.png",
            "Sport-baseball-icon.png"
    };

    @Override
    public void start(Stage stage) throws Exception {
        Image[] images =
                Arrays.stream(IMAGES_FILENAMES)
                .map(filename -> new Image(IMAGE_PATH_PREFIX + filename, true))
                .toArray(Image[]::new);

        DoubleExpression totalImageDownloadProgress;
        if (images.length > 0) {
            totalImageDownloadProgress = new SimpleDoubleProperty(0);
            for (Image image: images) {
                totalImageDownloadProgress = totalImageDownloadProgress.add(image.progressProperty());
            }
            totalImageDownloadProgress = totalImageDownloadProgress.divide(IMAGES_FILENAMES.length);
        } else {
            totalImageDownloadProgress = new SimpleDoubleProperty(1);
        }


        ProgressBar bar = new ProgressBar();
        bar.progressProperty().bind(totalImageDownloadProgress);

        VBox layout = new VBox(5, bar);

        Arrays.stream(images)
                .map(this::createImageView)
                .collect(Collectors.toCollection(layout::getChildren));

        stage.setScene(new Scene(layout));
        stage.show();
    }

    private ImageView createImageView(Image image) {
        ImageView imageView = new ImageView(image);
        imageView.setFitWidth(128);
        imageView.setFitHeight(128);

        return imageView;
    }

    public static void main(String[] args) {
        launch(args);
    }
}

The solution above does not account for error conditions for images that fail to load , but I'll leave adding such logic up to you (essentially monitor the error property and adjust the average calculation for the loading progress to not include those images which fail to load).

Thank you guys for your help, i found the answer :

 final Task<ArrayList<Image>> task = new Task<ArrayList<Image>>() {
            @Override protected ArrayList<Image> call() throws Exception {

                int id = Data_model.getInstance().currentid();

                All_photos photos = (All_photos) new parse_object <All_photos> (All_photos.class).ParseUri("https://api.edmunds.com/api/media/v2/styles/"+id+"/photos?api_key=id&fmt=json");

                ArrayList<String> list_href = new SlideShowHelper().get_href(photos);

                ArrayList<Image> list = new ArrayList<Image>();

                int i = 1;

                            for ( String st:list_href)
                            {

                                System.out.println(st);
                                list.add(new Image("https://media.ed.edmunds-media.com"+st+"",true));
                                updateProgress(i, list_href.size());
                                Thread.sleep(400);
                                i++;


                            }
                            return list;
            }


             @Override protected void succeeded() {

                 super.succeeded();

                 updateProgress(10, 10);

                 img_slideshow.setImage(Images.get(0));

                 int count1 =count+1;

                 lbl_slideshow.setText(""+count1+" / "+Images.size()+"");

                 progress_sd.setVisible(false);  

                 btn_sd_back.setVisible(true);
                 btn_sd_next.setVisible(true);


             }


         };

        task.addEventHandler(WorkerStateEvent.WORKER_STATE_SUCCEEDED,new EventHandler<WorkerStateEvent>() {

            public void handle(WorkerStateEvent t) {
                Images = task.getValue();

            }
        });

    new Thread(task).start();


    //progress_sd.visibleProperty().bind(task.runningProperty());

    progress_sd.progressProperty().bind(task.progressProperty());

}

it's working, But ? is it good ?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM