在 javafx 中下载图像时的进度条

Progress Bar while downloading image in javafx

你好 Whosebugers, 我会很短,所以我的问题是: 下载图像时如何在我的应用程序中显示进度条? 我做了一些研究,我发现了一些关于 "preloader" 和 "splach-screen" 的东西,但我们只能在启动我的主应用程序之前最后使用它们,关于进度条,我知道我必须绑定它,但是我怎样才能将它与我的图像绑定? 我感谢任何形式的帮助。

这是我创建简单幻灯片的代码:

@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+""));
    }
    }

只是要知道,该图像需要一段时间才能下载,这取决于互联网连接速度。

此答案回答了您的问题标题:"Progress Bar while downloading image in javafx"。

你问题中的代码有点不清楚,所以答案可能会也可能不会回答你真正想要实现的目标。

  1. 加载 background 中的图像。
  2. 将ProgressBar的进度属性绑定到图片的progessProperty

注意:对于示例代码和图像,图像加载速度非常快,因此您实际上看不到进度条在移动。对于正在加载的非常大图像和非常缓慢的互联网连接,您可能会看到进度条随着加载的进行而移动。

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);
    }
}

补充问题更新

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

使用 DoubleExpression,它映射到所有图像的背景加载进度的平均值。

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);
    }
}

上面的解决方案没有考虑 error conditions for images that fail to load,但我会把这样的逻辑留给你(主要是监控错误 属性 并将加载进度的平均计算调整为不包括那些无法加载的图像)。

谢谢大家的帮助,我找到了答案:

 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());

}

它正在工作,但是?好吃吗?