Summary
Add support for new constructors in the Image class to allow loading images in the background from InputStreams. Also clarify how background loading works for the existing constructors.
Problem
Images can only be loaded in the background when specified by URL. Loading from a URL only supports simple cases (from files or via HTTP with a GET request). If an image must be loaded in the background from a URL that uses a different method, or the data source is not accessible by URL, then the only means to load the image is via an InputStream. However InputStreams do not allow loading in the background and so its constructor will block until loading completes. This has implications on which thread Image objects should be constructed.
Solution
Existing constructors for URL support a "backgroundLoading" flag. Extend this support to the constructors that accept InputStreams.
Specification
--- a/modules/javafx.graphics/src/main/java/javafx/scene/image/Image.java
+++ b/modules/javafx.graphics/src/main/java/javafx/scene/image/Image.java
@@ -620,6 +620,9 @@ public class Image {
/**
* Constructs an {@code Image} with content loaded from the specified URL.
+ * <p>
+ * The image loading is performed immediately and is completed when this
+ * constructor returns.
*
* @param url a resource path, file path, or URL
* @throws NullPointerException if {@code url} is null
@@ -633,10 +636,14 @@ public class Image {
/**
* Constructs an {@code Image} with content loaded from the specified URL
* using the specified parameters.
+ * <p>
+ * If loading in the background is requested, then the {@link #progressProperty() progress} property can
+ * be monitored for loading progress. Otherwise, the image loading is performed
+ * immediately and is completed when this constructor returns.
*
* @param url a resource path, file path, or URL
* @param backgroundLoading indicates whether the image
- * is being loaded in the background
+ * should be loaded in the background
* @throws NullPointerException if {@code url} is null
* @throws IllegalArgumentException if {@code url} is invalid or unsupported
*/
@@ -648,6 +655,9 @@ public class Image {
/**
* Constructs an {@code Image} with content loaded from the specified URL
* using the specified parameters.
+ * <p>
+ * The image loading is performed immediately and is completed when this
+ * constructor returns.
*
* @param url a resource path, file path, or URL
* @param requestedWidth the image's bounding box width
@@ -671,6 +681,10 @@ public class Image {
/**
* Constructs an {@code Image} with content loaded from the specified URL
* using the specified parameters.
+ * <p>
+ * If loading in the background is requested, then the {@link #progressProperty() progress} property can
+ * be monitored for loading progress. Otherwise, the image loading is performed
+ * immediately and is completed when this constructor returns.
*
* @param url a resource path, file path, or URL
* @param requestedWidth the image's bounding box width
@@ -682,7 +696,7 @@ public class Image {
* algorithm or a faster one when scaling this image to fit within
* the specified bounding box
* @param backgroundLoading indicates whether the image
- * is being loaded in the background
+ * should be loaded in the background
* @throws NullPointerException if {@code url} is null
* @throws IllegalArgumentException if {@code url} is invalid or unsupported
*/
@@ -701,6 +715,9 @@ public class Image {
/**
* Constructs an {@code Image} with content loaded from the specified
* input stream.
+ * <p>
+ * The image loading is performed immediately and is completed when this
+ * constructor returns. The stream is consumed but not closed.
*
* @param is the stream from which to load the image
* @throws NullPointerException if input stream is null
@@ -710,8 +727,33 @@ public class Image {
initialize(null);
}
+ /**
+ * Constructs an {@code Image} with content loaded from the specified
+ * input stream.
+ * <p>
+ * If {@code backgroundLoading} is {@code true}, the {@link #progressProperty() progress} property
+ * can be monitored for loading progress. The stream will be consumed asynchronously;
+ * the caller must not read from or close it. It will be closed automatically when loading completes.
+ * <p>
+ * If {@code backgroundLoading} is {@code false}, the image is loaded immediately and
+ * completed when this constructor returns. The stream is consumed but not closed.
+ *
+ * @param is the stream from which to load the image
+ * @param backgroundLoading indicates whether the image
+ * should be loaded in the background
+ * @throws NullPointerException if input stream is null
+ * @since 26
+ */
+ public Image(@NamedArg("is") InputStream is, @NamedArg("backgroundLoading") boolean backgroundLoading) {
+ this(null, validateInputStream(is), 0, 0, false, false, backgroundLoading);
+ initialize(null);
+ }
+
/**
* Constructs a new {@code Image} with the specified parameters.
+ * <p>
+ * The image loading is performed immediately and is completed when this
+ * constructor returns. The stream is consumed but not closed.
*
* @param is the stream from which to load the image
* @param requestedWidth the image's bounding box width
@@ -731,6 +773,37 @@ public class Image {
initialize(null);
}
+ /**
+ * Constructs a new {@code Image} with the specified parameters.
+ * <p>
+ * If {@code backgroundLoading} is {@code true}, the {@link #progressProperty() progress} property
+ * can be monitored for loading progress. The stream will be consumed asynchronously;
+ * the caller must not read from or close it. It will be closed automatically when loading completes.
+ * <p>
+ * If {@code backgroundLoading} is {@code false}, the image is loaded immediately and
+ * completed when this constructor returns. The stream is consumed but not closed.
+ *
+ * @param is the stream from which to load the image
+ * @param requestedWidth the image's bounding box width
+ * @param requestedHeight the image's bounding box height
+ * @param preserveRatio indicates whether to preserve the aspect ratio of
+ * the original image when scaling to fit the image within the
+ * specified bounding box
+ * @param smooth indicates whether to use a better quality filtering
+ * algorithm or a faster one when scaling this image to fit within
+ * the specified bounding box
+ * @param backgroundLoading indicates whether the image
+ * should be loaded in the background
+ * @throws NullPointerException if input stream is null
+ * @since 26
+ */
+ public Image(@NamedArg("is") InputStream is, @NamedArg("requestedWidth") double requestedWidth, @NamedArg("requestedHeight") double requestedHeight,
+ @NamedArg("preserveRatio") boolean preserveRatio, @NamedArg("smooth") boolean smooth, @NamedArg("backgroundLoading") boolean backgroundLoading) {
+ this(null, validateInputStream(is), requestedWidth, requestedHeight,
+ preserveRatio, smooth, backgroundLoading);
+ initialize(null);
+ }
- csr of
-
JDK-8361286 Allow enabling of background loading for images loaded from an InputStream
-
- Resolved
-