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 javafx.embed.swing; 27 28 import java.awt.AlphaComposite; 29 import java.awt.Graphics2D; 30 import java.awt.image.BufferedImage; 31 import java.nio.IntBuffer; 32 import javafx.scene.image.Image; 33 import javafx.scene.image.PixelFormat; 34 import javafx.scene.image.PixelReader; 35 import javafx.scene.image.PixelWriter; 36 import javafx.scene.image.WritableImage; 37 import javafx.scene.image.WritablePixelFormat; 38 import sun.awt.image.IntegerComponentRaster; 39 40 /** 41 * This class provides utility methods for converting data types between 42 * Swing/AWT and JavaFX formats. 43 */ 44 public class SwingFXUtils { 45 private SwingFXUtils() {} // no instances 46 47 /** 48 * Snapshots the specified {@link BufferedImage} and stores a copy of 49 * its pixels into a JavaFX {@link Image} object, creating a new 50 * object if needed. 51 * The returned {@code Image} will be a static snapshot of the state 52 * of the pixels in the {@code BufferedImage} at the time the method 53 * completes. Further changes to the {@code BufferedImage} will not 54 * be reflected in the {@code Image}. 55 * <p> 56 * The optional JavaFX {@link WritableImage} parameter may be reused 57 * to store the copy of the pixels. 163 } else if (iw < bw || ih < bh) { 164 Graphics2D g2d = bimg.createGraphics(); 165 g2d.setComposite(AlphaComposite.Clear); 166 g2d.fillRect(0, 0, bw, bh); 167 g2d.dispose(); 168 } 169 } 170 if (bimg == null) { 171 bimg = new BufferedImage(iw, ih, BufferedImage.TYPE_INT_ARGB_PRE); 172 } 173 IntegerComponentRaster icr = (IntegerComponentRaster) bimg.getRaster(); 174 int offset = icr.getDataOffset(0); 175 int scan = icr.getScanlineStride(); 176 int data[] = icr.getDataStorage(); 177 WritablePixelFormat<IntBuffer> pf = (bimg.isAlphaPremultiplied() ? 178 PixelFormat.getIntArgbPreInstance() : 179 PixelFormat.getIntArgbInstance()); 180 pr.getPixels(0, 0, iw, ih, pf, data, offset, scan); 181 return bimg; 182 } 183 } | 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 javafx.embed.swing; 27 28 import java.awt.AlphaComposite; 29 import java.awt.EventQueue; 30 import java.awt.Graphics2D; 31 import java.awt.SecondaryLoop; 32 import java.awt.image.BufferedImage; 33 import java.lang.reflect.InvocationTargetException; 34 import java.lang.reflect.Method; 35 import java.nio.IntBuffer; 36 import java.security.AccessController; 37 import java.security.PrivilegedAction; 38 import java.util.concurrent.atomic.AtomicBoolean; 39 import javafx.application.Platform; 40 import javafx.scene.image.Image; 41 import javafx.scene.image.PixelFormat; 42 import javafx.scene.image.PixelReader; 43 import javafx.scene.image.PixelWriter; 44 import javafx.scene.image.WritableImage; 45 import javafx.scene.image.WritablePixelFormat; 46 import com.sun.javafx.application.PlatformImpl; 47 import com.sun.javafx.tk.Toolkit; 48 import sun.awt.AWTAccessor; 49 import sun.awt.FwDispatcher; 50 import sun.awt.image.IntegerComponentRaster; 51 52 /** 53 * This class provides utility methods for converting data types between 54 * Swing/AWT and JavaFX formats. 55 */ 56 public class SwingFXUtils { 57 private SwingFXUtils() {} // no instances 58 59 /** 60 * Snapshots the specified {@link BufferedImage} and stores a copy of 61 * its pixels into a JavaFX {@link Image} object, creating a new 62 * object if needed. 63 * The returned {@code Image} will be a static snapshot of the state 64 * of the pixels in the {@code BufferedImage} at the time the method 65 * completes. Further changes to the {@code BufferedImage} will not 66 * be reflected in the {@code Image}. 67 * <p> 68 * The optional JavaFX {@link WritableImage} parameter may be reused 69 * to store the copy of the pixels. 175 } else if (iw < bw || ih < bh) { 176 Graphics2D g2d = bimg.createGraphics(); 177 g2d.setComposite(AlphaComposite.Clear); 178 g2d.fillRect(0, 0, bw, bh); 179 g2d.dispose(); 180 } 181 } 182 if (bimg == null) { 183 bimg = new BufferedImage(iw, ih, BufferedImage.TYPE_INT_ARGB_PRE); 184 } 185 IntegerComponentRaster icr = (IntegerComponentRaster) bimg.getRaster(); 186 int offset = icr.getDataOffset(0); 187 int scan = icr.getScanlineStride(); 188 int data[] = icr.getDataStorage(); 189 WritablePixelFormat<IntBuffer> pf = (bimg.isAlphaPremultiplied() ? 190 PixelFormat.getIntArgbPreInstance() : 191 PixelFormat.getIntArgbInstance()); 192 pr.getPixels(0, 0, iw, ih, pf, data, offset, scan); 193 return bimg; 194 } 195 196 /** 197 * If called from the FX Application Thread 198 * invokes a runnable directly blocking the calling code 199 * Otherwise 200 * uses Platform.runLater without blocking 201 */ 202 static void runOnFxThread(Runnable runnable) { 203 if (Platform.isFxApplicationThread()) { 204 runnable.run(); 205 } else { 206 Platform.runLater(runnable); 207 } 208 } 209 210 private static class FwSecondaryLoop implements SecondaryLoop { 211 212 private final AtomicBoolean isRunning = new AtomicBoolean(false); 213 214 @Override public boolean enter() { 215 if (isRunning.compareAndSet(false, true)) { 216 PlatformImpl.runAndWait(new Runnable() { 217 @Override public void run() { 218 Toolkit.getToolkit().enterNestedEventLoop(FwSecondaryLoop.this); 219 } 220 }); 221 return true; 222 } 223 return false; 224 } 225 226 @Override public boolean exit() { 227 if (isRunning.compareAndSet(true, false)) { 228 PlatformImpl.runAndWait(new Runnable() { 229 @Override public void run() { 230 Toolkit.getToolkit().exitNestedEventLoop(FwSecondaryLoop.this, null); 231 } 232 }); 233 return true; 234 } 235 return false; 236 } 237 } 238 239 private static class FXDispatcher implements FwDispatcher { 240 @Override public boolean isDispatchThread() { 241 return Platform.isFxApplicationThread(); 242 } 243 244 @Override public void scheduleDispatch(Runnable runnable) { 245 runOnFxThread(runnable); 246 } 247 248 @Override public SecondaryLoop createSecondaryLoop() { 249 return new FwSecondaryLoop(); 250 } 251 } 252 253 //Called with reflection from PlatformImpl to avoid dependency 254 public static void installFwEventQueue() { 255 EventQueue eq = AccessController.doPrivileged( 256 new PrivilegedAction<EventQueue>() { 257 @Override public EventQueue run() { 258 return java.awt.Toolkit.getDefaultToolkit().getSystemEventQueue(); 259 } 260 }); 261 AWTAccessor.getEventQueueAccessor().setFwDispatcher(eq, new FXDispatcher()); 262 } 263 } |