Skip to content

Commit 98e64cf

Browse files
committed
8159055: Clarify handling of null and invalid image data for ImageIcon constructors and setImage method
Reviewed-by: aivanov, prr, abhiscxk, kizune, serb
1 parent e7d2a52 commit 98e64cf

File tree

2 files changed

+165
-0
lines changed

2 files changed

+165
-0
lines changed

src/java.desktop/share/classes/javax/swing/ImageIcon.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,14 @@
6363
* of the image.
6464
*
6565
* <p>
66+
* If the image source parameter to a constructor or method is non-null,
67+
* but does not reference valid accessible image data,
68+
* no exceptions will be thrown but no image will be rendered
69+
* even though {@link #getImage()} will return a non-null value,
70+
* as the image will have no dimensions
71+
* and {@link #getImageLoadStatus()} will report {@code MediaTracker.ERRORED}.
72+
*
73+
* <p>
6674
* For further information and examples of using image icons, see
6775
* <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/icon.html">How to Use Icons</a>
6876
* in <em>The Java Tutorial.</em>
@@ -178,6 +186,7 @@ public ImageIcon (String filename) {
178186
* of the image.
179187
* @param location the URL for the image
180188
* @param description a brief textual description of the image
189+
* @throws NullPointerException if {@code location} is {@code null}
181190
* @see #ImageIcon(String)
182191
*/
183192
public ImageIcon(URL location, String description) {
@@ -197,6 +206,7 @@ public ImageIcon(URL location, String description) {
197206
* The icon's description is initialized to be
198207
* a string representation of the URL.
199208
* @param location the URL for the image
209+
* @throws NullPointerException if {@code location} is {@code null}
200210
* @see #getDescription
201211
*/
202212
public ImageIcon (URL location) {
@@ -207,6 +217,7 @@ public ImageIcon (URL location) {
207217
* Creates an ImageIcon from the image.
208218
* @param image the image
209219
* @param description a brief textual description of the image
220+
* @throws NullPointerException if {@code image} is {@code null}
210221
*/
211222
public ImageIcon(Image image, String description) {
212223
this.image = image;
@@ -220,6 +231,7 @@ public ImageIcon(Image image, String description) {
220231
* If the image has a "comment" property that is a string,
221232
* then the string is used as the description of this icon.
222233
* @param image the image
234+
* @throws NullPointerException if {@code image} is {@code null}
223235
* @see #getDescription
224236
* @see java.awt.Image#getProperty
225237
*/
@@ -248,6 +260,7 @@ private static String getImageComment(Image image) {
248260
* @param imageData an array of pixels in an image format supported
249261
* by the AWT Toolkit, such as GIF, JPEG, or (as of 1.3) PNG
250262
* @param description a brief textual description of the image
263+
* @throws NullPointerException if {@code imageData} is {@code null}
251264
* @see java.awt.Toolkit#createImage
252265
*/
253266
public ImageIcon (byte[] imageData, String description) {
@@ -271,6 +284,7 @@ public ImageIcon (byte[] imageData, String description) {
271284
*
272285
* @param imageData an array of pixels in an image format supported by
273286
* the AWT Toolkit, such as GIF, JPEG, or (as of 1.3) PNG
287+
* @throws NullPointerException if {@code imageData} is {@code null}
274288
* @see java.awt.Toolkit#createImage
275289
* @see #getDescription
276290
* @see java.awt.Image#getProperty
@@ -375,6 +389,7 @@ public Image getImage() {
375389
/**
376390
* Sets the image displayed by this icon.
377391
* @param image the image
392+
* @throws NullPointerException if {@code image} is {@code null}
378393
*/
379394
public void setImage(Image image) {
380395
this.image = image;
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @bug 8159055
27+
* @summary Verifies null parameter and invalid data handling of
28+
* ImageIcon constructors and setImage method
29+
* @run main ImageIconTest
30+
*/
31+
32+
import java.io.File;
33+
import java.io.FileOutputStream;
34+
import java.net.URI;
35+
import java.net.URL;
36+
import java.util.Random;
37+
import java.awt.Image;
38+
import java.awt.Toolkit;
39+
import javax.swing.ImageIcon;
40+
41+
public class ImageIconTest {
42+
43+
static enum ArgType { FILE, URL, BYTE_ARRAY, IMAGE, SET_IMAGE };
44+
static enum ArgVal { NULL, INVALID_DATA };
45+
46+
public static void main(String[] args) throws Exception {
47+
48+
String imgName = "invalid.gif";
49+
byte[] invalidData = new byte[100];
50+
new Random().nextBytes(invalidData);
51+
try (FileOutputStream fos = new FileOutputStream(imgName)) {
52+
fos.write(invalidData);
53+
}
54+
File file = new File(imgName);
55+
file.deleteOnExit();
56+
57+
for (ArgType a : ArgType.values()) {
58+
for (final ArgVal v : ArgVal.values()) {
59+
System.out.println("Testing for ArgType " + a + " for case " + v);
60+
boolean expected = true;
61+
boolean passed = false;
62+
try {
63+
switch (a) {
64+
65+
case FILE :
66+
67+
expected = false;
68+
String s = (v == ArgVal.NULL) ? null : imgName;
69+
new ImageIcon(s);
70+
passed = true; // no exception expected for this case
71+
break;
72+
73+
case URL :
74+
75+
if (v == ArgVal.NULL) {
76+
77+
new ImageIcon((URL)null);
78+
79+
} else if (v == ArgVal.INVALID_DATA) {
80+
expected = false;
81+
new ImageIcon(new URI("file://" + imgName).toURL());
82+
passed = true; // no exception expected for this case
83+
84+
}
85+
break;
86+
87+
case BYTE_ARRAY :
88+
89+
if (v == ArgVal.NULL) {
90+
91+
byte[] bytes = null;
92+
new ImageIcon(bytes);
93+
94+
} else if (v == ArgVal.INVALID_DATA) {
95+
expected = false;
96+
97+
new ImageIcon(invalidData);
98+
99+
passed = true; // no exception expected for this case
100+
}
101+
break;
102+
103+
case IMAGE :
104+
105+
if (v == ArgVal.NULL) {
106+
107+
new ImageIcon((Image)null);
108+
109+
} else if (v == ArgVal.INVALID_DATA) {
110+
expected = false;
111+
112+
new ImageIcon((Image)Toolkit.getDefaultToolkit().createImage(imgName));
113+
114+
passed = true; // no exception expected for this case
115+
}
116+
break;
117+
118+
case SET_IMAGE :
119+
120+
ImageIcon ii = new ImageIcon();
121+
122+
if (v == ArgVal.NULL) {
123+
124+
ii.setImage((Image) null);
125+
126+
} else if (v == ArgVal.INVALID_DATA) {
127+
expected = false;
128+
129+
ii.setImage((Image)Toolkit.getDefaultToolkit().createImage(imgName));
130+
131+
passed = true; // no exception expected for this case
132+
}
133+
break;
134+
}
135+
} catch (NullPointerException e) {
136+
if (expected) {
137+
passed = true;
138+
}
139+
}
140+
if (expected && !passed) {
141+
throw new RuntimeException("Did not receive expected exception for : " + a);
142+
}
143+
if (!expected && !passed) {
144+
throw new RuntimeException("Received unexpected exception for : " + a);
145+
}
146+
}
147+
}
148+
149+
}
150+
}

0 commit comments

Comments
 (0)