JavaFX - 进度属性不起作用?

时间:2016-10-14 16:26:31

标签: javafx task progress

我正在尝试在加载另一张图片时获取我的图片查看器的进度值。我尝试了两种简单的方法,但它对我没用。

首先我使用progressProperty类中的Image

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”。

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

2 个答案:

答案 0 :(得分:1)

请勿尝试自行完成此操作。你不知道,已经加载了多少图像,除非你在加载之前找到图像的大小并从观察流的进度的蒸汽加载图像,这将是不必要的复杂。顺便说一句:您使用的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();
}

答案 1 :(得分:1)

您需要在后台加载Image,以便在完全加载图像之前返回对构造函数的调用。默认情况下,它会一直阻塞直到它被加载(因此当你向其添加监听器时,progress属性将为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已经支持开箱即用的后台加载。