Question in short:
How can I find out, that background loading of image
has failed just before imageView.setImage(image)
results in showing an empty picture although image.isError==false
and image.getException==null
?
Background:
In my simple JavaFX based photoviewer app I use a TableView() for showing a directory with jpg files. Whenever one selects an entry in the table the picture is loaded using javafx Image class and is shown using an ImageView.
I load the photos in background using true
in the parameter of the Image-constructor.
Once a photo is loaded I keep it in a list ("Cache") for faster "showing again"
Here the code snippet:
public Object getMediaContent() {
Image image = (Image) content;
if (!isMediaContentValid()) { //if not already loaded or image in cache is invalid
try {
System.out.println("getMediaContent loading " + fileOnDisk);
content = new Image(fileOnDisk.toUri().toString(), true); //true=load in Background
} catch (Exception e) {
//will not occur with backgroundLoading: image.getException will get the exception
System.out.println("Exception while loading:");
e.printStackTrace();
}
} else {
System.out.println(fileOnDisk.toString() + "in Cache :-)...Error="+ image.isError() + " Exception=" + image.getException());
}
return content;
}
In isMediaContentValid()
I test
image.isError()
is false
image.getException(
) is null
The problem:
When the user selects photos very quickly (e.g. by using cursor down key) images are still loaded in background (for the cache) while the next photo's loading has already started. My simple chache algorithm has problems to find out when I run out of memory because there might be enough memory when loading is started but not to complete all background tasks.
But I expected that this is not a problem because image.isError()
would report true
or image.getException()
would be != null
in this case. So I could free memory before retrying.
But isError()
reports false
, getException()
reports null
and the image is shown "empty" in imageView :-(
The question:
How can I find out, that background loading of image
has failed just before imageView.setImage(image)
?
How can I find out, that background loading of image has failed just before
imageView.setImage(image)
?
This is not possible. The whole point of loading the image in the background is that it's done asynchronously. There is no guarantee that the exception already occured at the time the method returns. You need to use a listener to the error
property to be notified of a failure to load the image.
Example
Image image = new Image("https://stackoverflow.com/abc.jpg", true); // this image does not (currently) exist
image.errorProperty().addListener(o -> {
System.err.println("Error Loading Image " + image.getUrl());
image.getException().printStackTrace();
});