1 /* 2 * Copyright (c) 2013, 2015, 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 import java.awt.Color; 25 import java.awt.Graphics; 26 import java.awt.Graphics2D; 27 import java.awt.Image; 28 import java.awt.Toolkit; 29 import java.awt.image.BufferedImage; 30 import java.io.File; 31 import java.lang.reflect.Method; 32 import java.net.URL; 33 import javax.imageio.ImageIO; 34 import sun.awt.OSInfo; 35 import sun.awt.SunHints; 36 import java.awt.MediaTracker; 37 import java.awt.geom.AffineTransform; 38 import java.awt.image.ImageObserver; 39 import java.util.Arrays; 40 import java.util.List; 41 import javax.swing.JPanel; 42 import sun.awt.SunToolkit; 43 import sun.awt.image.MultiResolutionImage; 44 45 /** 46 * @test 47 * @bug 8011059 48 * @author Alexander Scherbatiy 49 * @summary [macosx] Make JDK demos look perfect on retina displays 50 * @modules java.desktop/sun.awt 51 * java.desktop/sun.awt.image 52 * @run main MultiResolutionImageTest CUSTOM 53 * @run main MultiResolutionImageTest TOOLKIT_PREPARE 54 * @run main MultiResolutionImageTest TOOLKIT_LOAD 55 * @run main MultiResolutionImageTest TOOLKIT 56 */ 57 public class MultiResolutionImageTest { 58 59 private static final int IMAGE_WIDTH = 300; 60 private static final int IMAGE_HEIGHT = 200; 61 private static final Color COLOR_1X = Color.GREEN; 62 private static final Color COLOR_2X = Color.BLUE; 63 private static final String IMAGE_NAME_1X = "image.png"; 64 private static final String IMAGE_NAME_2X = "image@2x.png"; 65 66 public static void main(String[] args) throws Exception { 67 68 System.out.println("args: " + args.length); 69 70 if (args.length == 0) { 71 throw new RuntimeException("Not found a test"); 72 } 73 74 String test = args[0]; 75 76 System.out.println("TEST: " + test); 77 System.out.println("CHECK OS: " + checkOS()); 78 79 if ("CUSTOM".equals(test)) { 80 testCustomMultiResolutionImage(); 81 } else if (checkOS()) { 82 switch (test) { 83 case "CUSTOM": 84 break; 85 case "TOOLKIT_PREPARE": 86 testToolkitMultiResolutionImagePrepare(); 87 break; 88 case "TOOLKIT_LOAD": 89 testToolkitMultiResolutionImageLoad(); 90 break; 91 case "TOOLKIT": 92 testToolkitMultiResolutionImage(); 93 testImageNameTo2xParsing(); 94 break; 95 default: 96 throw new RuntimeException("Unknown test: " + test); 97 } 98 } 99 } 100 101 static boolean checkOS() { 102 return OSInfo.getOSType() == OSInfo.OSType.MACOSX; 103 } 104 105 public static void testCustomMultiResolutionImage() { 106 testCustomMultiResolutionImage(false); 107 testCustomMultiResolutionImage(true); 108 } 109 110 public static void testCustomMultiResolutionImage(boolean enableImageScaling) { 111 112 Image image = new MultiResolutionBufferedImage(); 113 114 // Same image size 115 BufferedImage bufferedImage = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT, 116 BufferedImage.TYPE_INT_RGB); 117 Graphics2D g2d = (Graphics2D) bufferedImage.getGraphics(); 118 setImageScalingHint(g2d, enableImageScaling); 119 g2d.drawImage(image, 0, 0, null); 120 checkColor(bufferedImage.getRGB(3 * IMAGE_WIDTH / 4, 3 * IMAGE_HEIGHT / 4), false); 121 122 // Twice image size 123 bufferedImage = new BufferedImage(2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, 124 BufferedImage.TYPE_INT_RGB); 125 g2d = (Graphics2D) bufferedImage.getGraphics(); 126 setImageScalingHint(g2d, enableImageScaling); 127 g2d.drawImage(image, 0, 0, 2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, null); 128 checkColor(bufferedImage.getRGB(3 * IMAGE_WIDTH / 2, 3 * IMAGE_HEIGHT / 2), enableImageScaling); 129 130 // Scale 2x 131 bufferedImage = new BufferedImage(2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB); 132 g2d = (Graphics2D) bufferedImage.getGraphics(); 133 setImageScalingHint(g2d, enableImageScaling); 134 g2d.scale(2, 2); 135 g2d.drawImage(image, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, null); 136 checkColor(bufferedImage.getRGB(3 * IMAGE_WIDTH / 2, 3 * IMAGE_HEIGHT / 2), enableImageScaling); 137 138 // Rotate 139 bufferedImage = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT, 140 BufferedImage.TYPE_INT_RGB); 141 g2d = (Graphics2D) bufferedImage.getGraphics(); 142 setImageScalingHint(g2d, enableImageScaling); 143 g2d.drawImage(image, 0, 0, null); 144 g2d.rotate(Math.PI / 4); 145 checkColor(bufferedImage.getRGB(3 * IMAGE_WIDTH / 4, 3 * IMAGE_HEIGHT / 4), false); 146 147 // Scale 2x and Rotate 148 bufferedImage = new BufferedImage(2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB); 149 g2d = (Graphics2D) bufferedImage.getGraphics(); 150 setImageScalingHint(g2d, enableImageScaling); 151 g2d.scale(-2, 2); 152 g2d.rotate(-Math.PI / 10); 153 g2d.drawImage(image, -IMAGE_WIDTH, 0, IMAGE_WIDTH, IMAGE_HEIGHT, null); 154 checkColor(bufferedImage.getRGB(3 * IMAGE_WIDTH / 2, 3 * IMAGE_HEIGHT / 2), enableImageScaling); 155 156 // General Transform 157 bufferedImage = new BufferedImage(2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB); 158 g2d = (Graphics2D) bufferedImage.getGraphics(); 159 setImageScalingHint(g2d, enableImageScaling); 160 float delta = 0.05f; 161 float cos = 1 - delta * delta / 2; 162 float sin = 1 + delta; 163 AffineTransform transform = new AffineTransform(2 * cos, 0.1, 0.3, -2 * sin, 10, -5); 164 g2d.setTransform(transform); 165 g2d.drawImage(image, 0, -IMAGE_HEIGHT, IMAGE_WIDTH, IMAGE_HEIGHT, null); 166 checkColor(bufferedImage.getRGB(3 * IMAGE_WIDTH / 2, 3 * IMAGE_HEIGHT / 2), enableImageScaling); 167 168 int D = 10; 169 // From Source to small Destination region 170 bufferedImage = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB); 171 g2d = (Graphics2D) bufferedImage.getGraphics(); 172 setImageScalingHint(g2d, enableImageScaling); 173 g2d.drawImage(image, IMAGE_WIDTH / 2, IMAGE_HEIGHT / 2, IMAGE_WIDTH - D, IMAGE_HEIGHT - D, 174 D, D, IMAGE_WIDTH - D, IMAGE_HEIGHT - D, null); 175 checkColor(bufferedImage.getRGB(3 * IMAGE_WIDTH / 4, 3 * IMAGE_HEIGHT / 4), false); 176 177 // From Source to large Destination region 178 bufferedImage = new BufferedImage(2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB); 179 g2d = (Graphics2D) bufferedImage.getGraphics(); 180 setImageScalingHint(g2d, enableImageScaling); 181 g2d.drawImage(image, D, D, 2 * IMAGE_WIDTH - D, 2 * IMAGE_HEIGHT - D, 182 IMAGE_WIDTH / 2, IMAGE_HEIGHT / 2, IMAGE_WIDTH - D, IMAGE_HEIGHT - D, null); 183 checkColor(bufferedImage.getRGB(3 * IMAGE_WIDTH / 2, 3 * IMAGE_HEIGHT / 2), enableImageScaling); 184 } 185 186 static class MultiResolutionBufferedImage extends BufferedImage 187 implements MultiResolutionImage { 188 189 Image highResolutionImage; 190 191 public MultiResolutionBufferedImage() { 192 super(IMAGE_WIDTH, IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB); 193 highResolutionImage = new BufferedImage( 194 2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB); 195 draw(getGraphics(), 1); 196 draw(highResolutionImage.getGraphics(), 2); 197 } 198 199 void draw(Graphics graphics, float resolution) { 200 Graphics2D g2 = (Graphics2D) graphics; 201 g2.scale(resolution, resolution); 202 g2.setColor((resolution == 1) ? COLOR_1X : COLOR_2X); 203 g2.fillRect(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT); 204 } 205 206 @Override 207 public Image getResolutionVariant(int width, int height) { 208 return ((width <= getWidth() && height <= getHeight())) 209 ? this : highResolutionImage; 210 } 211 212 @Override 213 public List<Image> getResolutionVariants() { 214 return Arrays.asList(this, highResolutionImage); 215 } 216 } 217 218 static void testToolkitMultiResolutionImagePrepare() throws Exception { 219 220 generateImages(); 221 222 File imageFile = new File(IMAGE_NAME_1X); 223 String fileName = imageFile.getAbsolutePath(); 224 225 Image image = Toolkit.getDefaultToolkit().getImage(fileName); 226 227 SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); 228 toolkit.prepareImage(image, IMAGE_WIDTH, IMAGE_HEIGHT, new LoadImageObserver(image)); 229 230 testToolkitMultiResolutionImageLoad(image); 231 } 232 233 static void testToolkitMultiResolutionImageLoad() throws Exception { 234 235 generateImages(); 236 237 File imageFile = new File(IMAGE_NAME_1X); 238 String fileName = imageFile.getAbsolutePath(); 239 Image image = Toolkit.getDefaultToolkit().getImage(fileName); 240 testToolkitMultiResolutionImageLoad(image); 241 } 242 243 static void testToolkitMultiResolutionImageLoad(Image image) throws Exception { 244 245 MediaTracker tracker = new MediaTracker(new JPanel()); 246 tracker.addImage(image, 0); 247 tracker.waitForID(0); 248 if (tracker.isErrorAny()) { 249 throw new RuntimeException("Error during image loading"); 250 } 251 tracker.removeImage(image, 0); 252 253 testImageLoaded(image); 254 255 int w = image.getWidth(null); 256 int h = image.getHeight(null); 257 258 Image resolutionVariant = ((MultiResolutionImage) image) 259 .getResolutionVariant(2 * w, 2 * h); 260 261 if (image == resolutionVariant) { 262 throw new RuntimeException("Resolution variant is not loaded"); 263 } 264 265 testImageLoaded(resolutionVariant); 266 } 267 268 static void testImageLoaded(Image image) { 269 270 SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); 271 272 int flags = toolkit.checkImage(image, IMAGE_WIDTH, IMAGE_WIDTH, new SilentImageObserver()); 273 if ((flags & (ImageObserver.FRAMEBITS | ImageObserver.ALLBITS)) == 0) { 274 throw new RuntimeException("Image is not loaded!"); 275 } 276 } 277 278 static class SilentImageObserver implements ImageObserver { 279 280 @Override 281 public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) { 282 throw new RuntimeException("Observer should not be called!"); 283 } 284 } 285 286 static class LoadImageObserver implements ImageObserver { 287 288 Image image; 289 290 public LoadImageObserver(Image image) { 291 this.image = image; 292 } 293 294 @Override 295 public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) { 296 297 if (image != img) { 298 throw new RuntimeException("Original image is not passed to the observer"); 299 } 300 301 if ((infoflags & ImageObserver.WIDTH) != 0) { 302 if (width != IMAGE_WIDTH) { 303 throw new RuntimeException("Original width is not passed to the observer"); 304 } 305 } 306 307 if ((infoflags & ImageObserver.HEIGHT) != 0) { 308 if (height != IMAGE_HEIGHT) { 309 throw new RuntimeException("Original height is not passed to the observer"); 310 } 311 } 312 313 return (infoflags & ALLBITS) == 0; 314 } 315 316 } 317 318 static void testToolkitMultiResolutionImage() throws Exception { 319 320 generateImages(); 321 322 File imageFile = new File(IMAGE_NAME_1X); 323 String fileName = imageFile.getAbsolutePath(); 324 URL url = imageFile.toURI().toURL(); 325 testToolkitMultiResolutionImageChache(fileName, url); 326 327 Image image = Toolkit.getDefaultToolkit().getImage(fileName); 328 testToolkitImageObserver(image); 329 testToolkitMultiResolutionImage(image, false); 330 testToolkitMultiResolutionImage(image, true); 331 332 image = Toolkit.getDefaultToolkit().getImage(url); 333 testToolkitImageObserver(image); 334 testToolkitMultiResolutionImage(image, false); 335 testToolkitMultiResolutionImage(image, true); 336 } 337 338 static void testToolkitMultiResolutionImageChache(String fileName, URL url) { 339 340 Image img1 = Toolkit.getDefaultToolkit().getImage(fileName); 341 if (!(img1 instanceof MultiResolutionImage)) { 342 throw new RuntimeException("Not a MultiResolutionImage"); 343 } 344 345 Image img2 = Toolkit.getDefaultToolkit().getImage(fileName); 346 if (img1 != img2) { 347 throw new RuntimeException("Image is not cached"); 348 } 349 350 img1 = Toolkit.getDefaultToolkit().getImage(url); 351 if (!(img1 instanceof MultiResolutionImage)) { 352 throw new RuntimeException("Not a MultiResolutionImage"); 353 } 354 355 img2 = Toolkit.getDefaultToolkit().getImage(url); 356 if (img1 != img2) { 357 throw new RuntimeException("Image is not cached"); 358 } 359 } 360 361 static void testToolkitMultiResolutionImage(Image image, boolean enableImageScaling) 362 throws Exception { 363 364 MediaTracker tracker = new MediaTracker(new JPanel()); 365 tracker.addImage(image, 0); 366 tracker.waitForID(0); 367 if (tracker.isErrorAny()) { 368 throw new RuntimeException("Error during image loading"); 369 } 370 371 final BufferedImage bufferedImage1x = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT, 372 BufferedImage.TYPE_INT_RGB); 373 Graphics2D g1x = (Graphics2D) bufferedImage1x.getGraphics(); 374 setImageScalingHint(g1x, false); 375 g1x.drawImage(image, 0, 0, null); 376 checkColor(bufferedImage1x.getRGB(3 * IMAGE_WIDTH / 4, 3 * IMAGE_HEIGHT / 4), false); 377 378 Image resolutionVariant = ((MultiResolutionImage) image). 379 getResolutionVariant(2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT); 380 381 if (resolutionVariant == null) { 382 throw new RuntimeException("Resolution variant is null"); 383 } 384 385 MediaTracker tracker2x = new MediaTracker(new JPanel()); 386 tracker2x.addImage(resolutionVariant, 0); 387 tracker2x.waitForID(0); 388 if (tracker2x.isErrorAny()) { 389 throw new RuntimeException("Error during scalable image loading"); 390 } 391 392 final BufferedImage bufferedImage2x = new BufferedImage(2 * IMAGE_WIDTH, 393 2 * IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB); 394 Graphics2D g2x = (Graphics2D) bufferedImage2x.getGraphics(); 395 setImageScalingHint(g2x, enableImageScaling); 396 g2x.drawImage(image, 0, 0, 2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, null); 397 checkColor(bufferedImage2x.getRGB(3 * IMAGE_WIDTH / 2, 3 * IMAGE_HEIGHT / 2), enableImageScaling); 398 399 if (!(image instanceof MultiResolutionImage)) { 400 throw new RuntimeException("Not a MultiResolutionImage"); 401 } 402 403 MultiResolutionImage multiResolutionImage = (MultiResolutionImage) image; 404 405 Image image1x = multiResolutionImage.getResolutionVariant(IMAGE_WIDTH, IMAGE_HEIGHT); 406 Image image2x = multiResolutionImage.getResolutionVariant(2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT); 407 408 if (image1x.getWidth(null) * 2 != image2x.getWidth(null) 409 || image1x.getHeight(null) * 2 != image2x.getHeight(null)) { 410 throw new RuntimeException("Wrong resolution variant size"); 411 } 412 } 413 414 static void testToolkitImageObserver(final Image image) { 415 416 ImageObserver observer = new ImageObserver() { 417 418 @Override 419 public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) { 420 421 if (img != image) { 422 throw new RuntimeException("Wrong image in observer"); 423 } 424 425 if ((infoflags & (ImageObserver.ERROR | ImageObserver.ABORT)) != 0) { 426 throw new RuntimeException("Error during image loading"); 427 } 428 429 return (infoflags & ImageObserver.ALLBITS) == 0; 430 431 } 432 }; 433 434 final BufferedImage bufferedImage2x = new BufferedImage(2 * IMAGE_WIDTH, 435 2 * IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB); 436 Graphics2D g2x = (Graphics2D) bufferedImage2x.getGraphics(); 437 setImageScalingHint(g2x, true); 438 439 g2x.drawImage(image, 0, 0, 2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, observer); 440 441 } 442 443 static void setImageScalingHint(Graphics2D g2d, boolean enableImageScaling) { 444 g2d.setRenderingHint(SunHints.KEY_RESOLUTION_VARIANT, enableImageScaling 445 ? SunHints.VALUE_RESOLUTION_VARIANT_ON 446 : SunHints.VALUE_RESOLUTION_VARIANT_OFF); 447 } 448 449 static void checkColor(int rgb, boolean isImageScaled) { 450 451 if (!isImageScaled && COLOR_1X.getRGB() != rgb) { 452 throw new RuntimeException("Wrong 1x color: " + new Color(rgb)); 453 } 454 455 if (isImageScaled && COLOR_2X.getRGB() != rgb) { 456 throw new RuntimeException("Wrong 2x color" + new Color(rgb)); 457 } 458 } 459 460 static void generateImages() throws Exception { 461 if (!new File(IMAGE_NAME_1X).exists()) { 462 generateImage(1); 463 } 464 465 if (!new File(IMAGE_NAME_2X).exists()) { 466 generateImage(2); 467 } 468 } 469 470 static void generateImage(int scale) throws Exception { 471 BufferedImage image = new BufferedImage(scale * IMAGE_WIDTH, scale * IMAGE_HEIGHT, 472 BufferedImage.TYPE_INT_RGB); 473 Graphics g = image.getGraphics(); 474 g.setColor(scale == 1 ? COLOR_1X : COLOR_2X); 475 g.fillRect(0, 0, scale * IMAGE_WIDTH, scale * IMAGE_HEIGHT); 476 File file = new File(scale == 1 ? IMAGE_NAME_1X : IMAGE_NAME_2X); 477 ImageIO.write(image, "png", file); 478 } 479 480 static void testImageNameTo2xParsing() throws Exception { 481 482 for (String[] testNames : TEST_FILE_NAMES) { 483 String testName = testNames[0]; 484 String goldenName = testNames[1]; 485 String resultName = getTestScaledImageName(testName); 486 487 if (!isValidPath(testName) && resultName == null) { 488 continue; 489 } 490 491 if (goldenName.equals(resultName)) { 492 continue; 493 } 494 495 throw new RuntimeException("Test name " + testName 496 + ", result name: " + resultName); 497 } 498 499 for (URL[] testURLs : TEST_URLS) { 500 URL testURL = testURLs[0]; 501 URL goldenURL = testURLs[1]; 502 URL resultURL = getTestScaledImageURL(testURL); 503 504 if (!isValidPath(testURL.getPath()) && resultURL == null) { 505 continue; 506 } 507 508 if (goldenURL.equals(resultURL)) { 509 continue; 510 } 511 512 throw new RuntimeException("Test url: " + testURL 513 + ", result url: " + resultURL); 514 } 515 516 } 517 518 static URL getTestScaledImageURL(URL url) throws Exception { 519 Method method = getScalableImageMethod("getScaledImageURL", URL.class); 520 return (URL) method.invoke(null, url); 521 } 522 523 static String getTestScaledImageName(String name) throws Exception { 524 Method method = getScalableImageMethod("getScaledImageName", String.class); 525 return (String) method.invoke(null, name); 526 } 527 528 private static boolean isValidPath(String path) { 529 return !path.isEmpty() && !path.endsWith("/") && !path.endsWith(".") 530 && !path.contains("@2x"); 531 } 532 533 private static Method getScalableImageMethod(String name, 534 Class... parameterTypes) throws Exception { 535 Toolkit toolkit = Toolkit.getDefaultToolkit(); 536 Method method = toolkit.getClass().getDeclaredMethod(name, parameterTypes); 537 method.setAccessible(true); 538 return method; 539 } 540 private static final String[][] TEST_FILE_NAMES; 541 private static final URL[][] TEST_URLS; 542 543 static { 544 TEST_FILE_NAMES = new String[][]{ 545 {"", null}, 546 {".", null}, 547 {"..", null}, 548 {"/", null}, 549 {"/.", null}, 550 {"dir/", null}, 551 {"dir/.", null}, 552 {"aaa@2x.png", null}, 553 {"/dir/aaa@2x.png", null}, 554 {"image", "image@2x"}, 555 {"image.ext", "image@2x.ext"}, 556 {"image.aaa.ext", "image.aaa@2x.ext"}, 557 {"dir/image", "dir/image@2x"}, 558 {"dir/image.ext", "dir/image@2x.ext"}, 559 {"dir/image.aaa.ext", "dir/image.aaa@2x.ext"}, 560 {"dir/aaa.bbb/image", "dir/aaa.bbb/image@2x"}, 561 {"dir/aaa.bbb/image.ext", "dir/aaa.bbb/image@2x.ext"}, 562 {"dir/aaa.bbb/image.ccc.ext", "dir/aaa.bbb/image.ccc@2x.ext"}, 563 {"/dir/image", "/dir/image@2x"}, 564 {"/dir/image.ext", "/dir/image@2x.ext"}, 565 {"/dir/image.aaa.ext", "/dir/image.aaa@2x.ext"}, 566 {"/dir/aaa.bbb/image", "/dir/aaa.bbb/image@2x"}, 567 {"/dir/aaa.bbb/image.ext", "/dir/aaa.bbb/image@2x.ext"}, 568 {"/dir/aaa.bbb/image.ccc.ext", "/dir/aaa.bbb/image.ccc@2x.ext"} 569 }; 570 try { 571 TEST_URLS = new URL[][]{ 572 // file 573 {new URL("file:/aaa"), new URL("file:/aaa@2x")}, 574 {new URL("file:/aaa.ext"), new URL("file:/aaa@2x.ext")}, 575 {new URL("file:/aaa.bbb.ext"), new URL("file:/aaa.bbb@2x.ext")}, 576 {new URL("file:/ccc/aaa.bbb.ext"), 577 new URL("file:/ccc/aaa.bbb@2x.ext")}, 578 {new URL("file:/ccc.ddd/aaa.bbb.ext"), 579 new URL("file:/ccc.ddd/aaa.bbb@2x.ext")}, 580 {new URL("file:///~/image"), new URL("file:///~/image@2x")}, 581 {new URL("file:///~/image.ext"), 582 new URL("file:///~/image@2x.ext")}, 583 // http 584 {new URL("http://www.test.com"), null}, 585 {new URL("http://www.test.com/"), null}, 586 {new URL("http://www.test.com///"), null}, 587 {new URL("http://www.test.com/image"), 588 new URL("http://www.test.com/image@2x")}, 589 {new URL("http://www.test.com/image.ext"), 590 new URL("http://www.test.com/image@2x.ext")}, 591 {new URL("http://www.test.com/dir/image"), 592 new URL("http://www.test.com/dir/image@2x")}, 593 {new URL("http://www.test.com:80/dir/image.aaa.ext"), 594 new URL("http://www.test.com:80/dir/image.aaa@2x.ext")}, 595 {new URL("http://www.test.com:8080/dir/image.aaa.ext"), 596 new URL("http://www.test.com:8080/dir/image.aaa@2x.ext")}, 597 // jar 598 {new URL("jar:file:/dir/Java2D.jar!/image"), 599 new URL("jar:file:/dir/Java2D.jar!/image@2x")}, 600 {new URL("jar:file:/dir/Java2D.jar!/image.aaa.ext"), 601 new URL("jar:file:/dir/Java2D.jar!/image.aaa@2x.ext")}, 602 {new URL("jar:file:/dir/Java2D.jar!/images/image"), 603 new URL("jar:file:/dir/Java2D.jar!/images/image@2x")}, 604 {new URL("jar:file:/dir/Java2D.jar!/images/image.ext"), 605 new URL("jar:file:/dir/Java2D.jar!/images/image@2x.ext")}, 606 {new URL("jar:file:/aaa.bbb/Java2D.jar!/images/image.ext"), 607 new URL("jar:file:/aaa.bbb/Java2D.jar!/images/image@2x.ext")}, 608 {new URL("jar:file:/dir/Java2D.jar!/aaa.bbb/image.ext"), 609 new URL("jar:file:/dir/Java2D.jar!/aaa.bbb/image@2x.ext")},}; 610 } catch (Exception e) { 611 throw new RuntimeException(e); 612 } 613 } 614 615 static class PreloadedImageObserver implements ImageObserver { 616 617 @Override 618 public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) { 619 throw new RuntimeException("Image should be already preloaded"); 620 } 621 } 622 }