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 java.util.Set;
33 import java.util.HashSet;
34 import javafx.application.Platform;
35 import javafx.scene.image.Image;
36 import javafx.scene.image.PixelFormat;
37 import javafx.scene.image.PixelReader;
38 import javafx.scene.image.PixelWriter;
39 import javafx.scene.image.WritableImage;
40 import javafx.scene.image.WritablePixelFormat;
41 import javafx.scene.paint.Color;
42 import com.sun.javafx.tk.Toolkit;
43 import javax.swing.SwingUtilities;
44 import sun.awt.image.IntegerComponentRaster;
45
46 /**
47 * This class provides utility methods for converting data types between
48 * Swing/AWT and JavaFX formats.
49 * @since JavaFX 2.2
50 */
51 public class SwingFXUtils {
52 private SwingFXUtils() {} // no instances
53
54 /**
55 * Snapshots the specified {@link BufferedImage} and stores a copy of
56 * its pixels into a JavaFX {@link Image} object, creating a new
57 * object if needed.
58 * The returned {@code Image} will be a static snapshot of the state
59 * of the pixels in the {@code BufferedImage} at the time the method
60 * completes. Further changes to the {@code BufferedImage} will not
61 * be reflected in the {@code Image}.
62 * <p>
63 * The optional JavaFX {@link WritableImage} parameter may be reused
64 * to store the copy of the pixels.
94 int iw = (int) wimg.getWidth();
95 int ih = (int) wimg.getHeight();
96 if (iw < bw || ih < bh) {
97 wimg = null;
98 } else if (bw < iw || bh < ih) {
99 int empty[] = new int[iw];
100 PixelWriter pw = wimg.getPixelWriter();
101 PixelFormat<IntBuffer> pf = PixelFormat.getIntArgbPreInstance();
102 if (bw < iw) {
103 pw.setPixels(bw, 0, iw-bw, bh, pf, empty, 0, 0);
104 }
105 if (bh < ih) {
106 pw.setPixels(0, bh, iw, ih-bh, pf, empty, 0, 0);
107 }
108 }
109 }
110 if (wimg == null) {
111 wimg = new WritableImage(bw, bh);
112 }
113 PixelWriter pw = wimg.getPixelWriter();
114 IntegerComponentRaster icr = (IntegerComponentRaster) bimg.getRaster();
115 int data[] = icr.getDataStorage();
116 int offset = icr.getDataOffset(0);
117 int scan = icr.getScanlineStride();
118 PixelFormat<IntBuffer> pf = (bimg.isAlphaPremultiplied() ?
119 PixelFormat.getIntArgbPreInstance() :
120 PixelFormat.getIntArgbInstance());
121 pw.setPixels(0, 0, bw, bh, pf, data, offset, scan);
122 return wimg;
123 }
124
125 /**
126 * Determine the optimal BufferedImage type to use for the specified
127 * {@code fxFormat} allowing for the specified {@code bimg} to be used
128 * as a potential default storage space if it is not null and is compatible.
129 *
130 * @param fxFormat the PixelFormat of the source FX Image
131 * @param bimg an optional existing {@code BufferedImage} to be used
132 * for storage if it is compatible, or null
133 * @return
134 */
135 static int
136 getBestBufferedImageType(PixelFormat<?> fxFormat, BufferedImage bimg,
137 boolean isOpaque)
264 case BYTE_RGB:
265 srcPixelsAreOpaque = true;
266 break;
267 }
268 int prefBimgType = getBestBufferedImageType(pr.getPixelFormat(), bimg, srcPixelsAreOpaque);
269 if (bimg != null) {
270 int bw = bimg.getWidth();
271 int bh = bimg.getHeight();
272 if (bw < iw || bh < ih || bimg.getType() != prefBimgType) {
273 bimg = null;
274 } else if (iw < bw || ih < bh) {
275 Graphics2D g2d = bimg.createGraphics();
276 g2d.setComposite(AlphaComposite.Clear);
277 g2d.fillRect(0, 0, bw, bh);
278 g2d.dispose();
279 }
280 }
281 if (bimg == null) {
282 bimg = new BufferedImage(iw, ih, prefBimgType);
283 }
284 IntegerComponentRaster icr = (IntegerComponentRaster) bimg.getRaster();
285 int offset = icr.getDataOffset(0);
286 int scan = icr.getScanlineStride();
287 int data[] = icr.getDataStorage();
288 WritablePixelFormat<IntBuffer> pf = getAssociatedPixelFormat(bimg);
289 pr.getPixels(0, 0, iw, ih, pf, data, offset, scan);
290 return bimg;
291 }
292
293 /**
294 * If called from the FX Application Thread
295 * invokes a runnable directly blocking the calling code
296 * Otherwise
297 * uses Platform.runLater without blocking
298 */
299 static void runOnFxThread(Runnable runnable) {
300 if (Platform.isFxApplicationThread()) {
301 runnable.run();
302 } else {
303 Platform.runLater(runnable);
304 }
305 }
306
307 /**
|
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 java.util.Set;
33 import java.util.HashSet;
34 import javafx.application.Platform;
35 import javafx.scene.image.Image;
36 import javafx.scene.image.PixelFormat;
37 import javafx.scene.image.PixelReader;
38 import javafx.scene.image.PixelWriter;
39 import javafx.scene.image.WritableImage;
40 import javafx.scene.image.WritablePixelFormat;
41 import javafx.scene.paint.Color;
42 import com.sun.javafx.tk.Toolkit;
43 import javax.swing.SwingUtilities;
44
45 import jdk.swing.interop.SwingInterOpUtils;
46
47 /**
48 * This class provides utility methods for converting data types between
49 * Swing/AWT and JavaFX formats.
50 * @since JavaFX 2.2
51 */
52 public class SwingFXUtils {
53 private SwingFXUtils() {} // no instances
54
55 /**
56 * Snapshots the specified {@link BufferedImage} and stores a copy of
57 * its pixels into a JavaFX {@link Image} object, creating a new
58 * object if needed.
59 * The returned {@code Image} will be a static snapshot of the state
60 * of the pixels in the {@code BufferedImage} at the time the method
61 * completes. Further changes to the {@code BufferedImage} will not
62 * be reflected in the {@code Image}.
63 * <p>
64 * The optional JavaFX {@link WritableImage} parameter may be reused
65 * to store the copy of the pixels.
95 int iw = (int) wimg.getWidth();
96 int ih = (int) wimg.getHeight();
97 if (iw < bw || ih < bh) {
98 wimg = null;
99 } else if (bw < iw || bh < ih) {
100 int empty[] = new int[iw];
101 PixelWriter pw = wimg.getPixelWriter();
102 PixelFormat<IntBuffer> pf = PixelFormat.getIntArgbPreInstance();
103 if (bw < iw) {
104 pw.setPixels(bw, 0, iw-bw, bh, pf, empty, 0, 0);
105 }
106 if (bh < ih) {
107 pw.setPixels(0, bh, iw, ih-bh, pf, empty, 0, 0);
108 }
109 }
110 }
111 if (wimg == null) {
112 wimg = new WritableImage(bw, bh);
113 }
114 PixelWriter pw = wimg.getPixelWriter();
115 int data[] = SwingInterOpUtils.getData(bimg);
116 int offset = SwingInterOpUtils.getOffset(bimg);
117 int scan = SwingInterOpUtils.getScanlineStride(bimg);
118
119 PixelFormat<IntBuffer> pf = (bimg.isAlphaPremultiplied() ?
120 PixelFormat.getIntArgbPreInstance() :
121 PixelFormat.getIntArgbInstance());
122 pw.setPixels(0, 0, bw, bh, pf, data, offset, scan);
123 return wimg;
124 }
125
126 /**
127 * Determine the optimal BufferedImage type to use for the specified
128 * {@code fxFormat} allowing for the specified {@code bimg} to be used
129 * as a potential default storage space if it is not null and is compatible.
130 *
131 * @param fxFormat the PixelFormat of the source FX Image
132 * @param bimg an optional existing {@code BufferedImage} to be used
133 * for storage if it is compatible, or null
134 * @return
135 */
136 static int
137 getBestBufferedImageType(PixelFormat<?> fxFormat, BufferedImage bimg,
138 boolean isOpaque)
265 case BYTE_RGB:
266 srcPixelsAreOpaque = true;
267 break;
268 }
269 int prefBimgType = getBestBufferedImageType(pr.getPixelFormat(), bimg, srcPixelsAreOpaque);
270 if (bimg != null) {
271 int bw = bimg.getWidth();
272 int bh = bimg.getHeight();
273 if (bw < iw || bh < ih || bimg.getType() != prefBimgType) {
274 bimg = null;
275 } else if (iw < bw || ih < bh) {
276 Graphics2D g2d = bimg.createGraphics();
277 g2d.setComposite(AlphaComposite.Clear);
278 g2d.fillRect(0, 0, bw, bh);
279 g2d.dispose();
280 }
281 }
282 if (bimg == null) {
283 bimg = new BufferedImage(iw, ih, prefBimgType);
284 }
285 int offset = SwingInterOpUtils.getOffset(bimg);
286 int scan = SwingInterOpUtils.getScanlineStride(bimg);
287 int data[] = SwingInterOpUtils.getData(bimg);
288
289 WritablePixelFormat<IntBuffer> pf = getAssociatedPixelFormat(bimg);
290 pr.getPixels(0, 0, iw, ih, pf, data, offset, scan);
291 return bimg;
292 }
293
294 /**
295 * If called from the FX Application Thread
296 * invokes a runnable directly blocking the calling code
297 * Otherwise
298 * uses Platform.runLater without blocking
299 */
300 static void runOnFxThread(Runnable runnable) {
301 if (Platform.isFxApplicationThread()) {
302 runnable.run();
303 } else {
304 Platform.runLater(runnable);
305 }
306 }
307
308 /**
|