1 /*
2 * Copyright (c) 2014, 2016 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package test.javafx.embed.swing;
27
28 import java.awt.image.BufferedImage;
29 import java.util.concurrent.CountDownLatch;
30 import java.util.concurrent.TimeUnit;
31 import javafx.application.Application;
32 import javafx.application.Platform;
33 import javafx.embed.swing.SwingFXUtils;
34 import javafx.scene.image.Image;
35 import javafx.scene.image.PixelFormat;
36 import javafx.scene.image.PixelReader;
37 import javafx.stage.Stage;
38 import junit.framework.AssertionFailedError;
39 import org.junit.AfterClass;
40 import static org.junit.Assert.assertEquals;
41 import static org.junit.Assert.assertNotNull;
42 import static org.junit.Assert.assertTrue;
43 import org.junit.BeforeClass;
44 import org.junit.Test;
45
46 public class SwingFXUtilsTest {
47 static final boolean verbose = false;
48
49 // Used to launch the application before running any test
50 private static final CountDownLatch launchLatch = new CountDownLatch(1);
51
52 // Application class. An instance is created and initialized before running
53 // the first test, and it lives through the execution of all tests.
54 public static class MyApp extends Application {
55 @Override
56 public void start(Stage primaryStage) throws Exception {
57 Platform.setImplicitExit(false);
58 assertTrue(Platform.isFxApplicationThread());
59 assertNotNull(primaryStage);
60
61 launchLatch.countDown();
62 }
63 }
64
65 @BeforeClass
66 public static void doSetupOnce() {
67 // Start the Application
68 new Thread(() -> Application.launch(MyApp.class, (String[]) null)).start();
69
70 try {
71 if (!launchLatch.await(5000, TimeUnit.MILLISECONDS)) {
72 throw new AssertionFailedError("Timeout waiting for Application to launch");
73 }
74 } catch (InterruptedException ex) {
75 AssertionFailedError err = new AssertionFailedError("Unexpected exception");
76 err.initCause(ex);
77 throw err;
78 }
79
80 assertEquals(0, launchLatch.getCount());
81 }
82
83 @AfterClass
84 public static void doTeardownOnce() {
85 Platform.exit();
86 }
87
88 @Test
89 public void testFromFXImg() {
90 testFromFXImg("alpha.png");
91 testFromFXImg("opaque.gif");
92 testFromFXImg("opaque.jpg");
93 testFromFXImg("opaque.png");
94 testFromFXImg("trans.gif");
95 }
96
97 static void testFromFXImg(String imgfilename) {
98 Image img = new Image("test/javafx/embed/swing/"+imgfilename);
99 boolean rgbrequired = (img.getPixelReader().getPixelFormat().getType() == PixelFormat.Type.BYTE_RGB);
100 BufferedImage bimg = SwingFXUtils.fromFXImage(img, null);
101 checkBimg(img, bimg);
102 boolean reusesitself = reusesBimg(img, bimg, true);
103 boolean reusesxrgb = reusesBimg(img, BufferedImage.TYPE_INT_RGB, rgbrequired);
104 boolean reusesargb = reusesBimg(img, BufferedImage.TYPE_INT_ARGB, true);
105 boolean reusesargbpre = reusesBimg(img, BufferedImage.TYPE_INT_ARGB_PRE, true);
106 if (verbose) {
107 System.out.println(imgfilename+" type = "+img.getPixelReader().getPixelFormat());
108 System.out.println(imgfilename+" bimg type = "+bimg.getType());
109 System.out.println(imgfilename+" reuses own bimg = "+reusesitself);
110 System.out.println(imgfilename+" reuses rgb bimg = "+reusesxrgb);
111 System.out.println(imgfilename+" reuses argb bimg = "+reusesargb);
112 System.out.println(imgfilename+" reuses argb pre bimg = "+reusesargbpre);
113 System.out.println();
114 }
115 }
116
117 static boolean reusesBimg(Image img, int type, boolean required) {
118 int iw = (int) img.getWidth();
119 int ih = (int) img.getHeight();
120 BufferedImage bimg = new BufferedImage(iw, ih, type);
121 return reusesBimg(img, bimg, required);
122 }
123
124 static boolean reusesBimg(Image img, BufferedImage bimg, boolean required) {
125 BufferedImage ret = SwingFXUtils.fromFXImage(img, bimg);
126 checkBimg(img, ret);
127 if (required) {
128 assertTrue(bimg == ret);
129 }
130 return (bimg == ret);
131 }
132
133 static void checkBimg(Image img, BufferedImage bimg) {
134 PixelReader pr = img.getPixelReader();
135 int iw = (int) img.getWidth();
136 int ih = (int) img.getHeight();
137 for (int y = 0; y < ih; y++) {
138 for (int x = 0; x < iw; x++) {
139 int imgargb = pr.getArgb(x, y);
140 int bimgargb = bimg.getRGB(x, y);
141 if (imgargb != bimgargb) {
142 System.err.println(">>>> wrong color in bimg: "+hex(bimgargb)+
143 " at "+x+", "+y+
144 " should be: "+hex(imgargb));
145 assertEquals(imgargb, bimgargb);
146 }
147 }
148 }
149 }
150
151 static String hex(int i) {
152 return String.format("0x%08x", i);
153 }
154 }