JavaFX - 进度属性不起作用?

JavaFX - Progress properties don't work?

我正在尝试在加载另一张图片时获取我的图片查看器的进度值。我已经尝试了两种简单的方法来做到这一点,但对我来说没有用。

首先我使用 Image class 中的 progressProperty:

public boolean nextImageClicked()
{
    if(PICTURE_INDEX < picturePaths.size() - 1)
    {
        String path = picturePaths.get(PICTURE_INDEX + 1).toURI().toString();
        Image newImage = new Image(path);
        newImage.progressProperty().addListener((observable, oldValue, newValue) -> System.out.println("Current progress: "+newValue));
        GUI.getImageView().setImage(newImage);
        adjustImageViewBounds();
        PICTURE_INDEX += 1;
        return true;
    }
    else return false;
}

它没有在控制台上打印出任何东西,因为进度值没有发生奇怪的变化。所以我尝试将所有工作内容放在 Task<Void> 中,并通过 Task:

获取进度值
public boolean nextClicked()
{
    if(PICTURE_INDEX < picturePaths.size() - 1)
    {
        Task<Void> task = new Task<Void>()
        {
            @Override protected Void call() throws Exception 
            {
                String path = picturePaths.get(PICTURE_INDEX + 1).toURI().toString();
                Image newImage = new Image(path);
                GUI.getImageView().setImage(newImage);
                adjustImageViewBounds();
                PICTURE_INDEX += 1;
                return null;
            }
        };
        task.setOnRunning(e -> System.out.println(task.getProgress()));
        task.progressProperty().addListener((observable, oldValue, newValue) -> 
        {
            System.out.println(newValue);
        });
        task.run(); 
        return true;
    }
    else return false;
}

也没有如愿。

task.setOnRunning(e -> System.out.println(task.getProgress()));

我实现这个是为了查看默认值,它打印出“-1”。

我需要更改什么才能让控制台 return 单个进度值,如“0.1”、“0.14”?

不要尝试自己做这件事。你不知道图像已经加载了多少,除非你在加载之前找到图像的大小并从观察流进程的蒸汽中加载图像,这会不必要地复杂。顺便说一句:当图像完全加载时,您使用 returns 的 Image 构造函数。但是,您可以指定要异步加载的图像 by using the right constructorImage 提供一个progress 属性 来观察加载进度:

@Override
public void start(Stage primaryStage) {
    ImageView iv = new ImageView();
    ProgressBar pb = new ProgressBar();
    Button btn = new Button("Load Image");
    btn.setOnAction((ActionEvent event) -> {
        // ca. 6 MB image loaded from web
        Image image = new Image("http://eoimages.gsfc.nasa.gov/images/imagerecords/79000/79793/city_lights_africa_8k.jpg", true);
        pb.progressProperty().bind(image.progressProperty());
        iv.setImage(image);
    });

    ScrollPane sp = new ScrollPane(iv);
    VBox.setVgrow(sp, Priority.ALWAYS);
    VBox root = new VBox(btn, pb, sp);
    root.setFillWidth(true);

    Scene scene = new Scene(root);
    primaryStage.setMaximized(true);

    primaryStage.setScene(scene);
    primaryStage.show();
}

您需要Image在后台加载,以便在图像完全加载之前调用构造函数returns。默认情况下,它将阻塞直到加载(因此当您将侦听器添加到它时,进度 属性 将是 1):

public boolean nextImageClicked()
{
    if(PICTURE_INDEX < picturePaths.size() - 1)
    {
        String path = picturePaths.get(PICTURE_INDEX + 1).toURI().toString();

        // note additional parameter:
        Image newImage = new Image(path, true);

        newImage.progressProperty().addListener((observable, oldValue, newValue) -> System.out.println("Current progress: "+newValue));
        GUI.getImageView().setImage(newImage);
        adjustImageViewBounds();
        PICTURE_INDEX += 1;
        return true;
    }
    else return false;
}

要更改 Task 的进度,您需要在任务上显式调用 updateProgress(...)。知道要传递什么的唯一方法是观察图像的进度并将其传递给任务的进度,因此您只会得到上面代码的更复杂版本。这不是一个很好的任务用例,因为 Image 已经支持开箱即用的后台加载。