Edit C:\Program Files\Java\jdk1.8.0_121\javafx\embed\swing\SwingFXUtils.java
/* * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * * * * * * * * * * * * * * * * * * * */ package javafx.embed.swing; import java.awt.AlphaComposite; import java.awt.EventQueue; import java.awt.Graphics2D; import java.awt.SecondaryLoop; import java.awt.image.BufferedImage; import java.nio.IntBuffer; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Set; import java.util.HashSet; import java.util.concurrent.atomic.AtomicBoolean; import javafx.application.Platform; import javafx.scene.image.Image; import javafx.scene.image.PixelFormat; import javafx.scene.image.PixelReader; import javafx.scene.image.PixelWriter; import javafx.scene.image.WritableImage; import javafx.scene.image.WritablePixelFormat; import com.sun.javafx.application.PlatformImpl; import com.sun.javafx.tk.Toolkit; import sun.awt.AWTAccessor; import sun.awt.FwDispatcher; import sun.awt.image.IntegerComponentRaster; import javax.swing.*; /** * This class provides utility methods for converting data types between * Swing/AWT and JavaFX formats. * @since JavaFX 2.2 */ public class SwingFXUtils { private SwingFXUtils() {} // no instances /** * Snapshots the specified {@link BufferedImage} and stores a copy of * its pixels into a JavaFX {@link Image} object, creating a new * object if needed. * The returned {@code Image} will be a static snapshot of the state * of the pixels in the {@code BufferedImage} at the time the method * completes. Further changes to the {@code BufferedImage} will not * be reflected in the {@code Image}. * <p> * The optional JavaFX {@link WritableImage} parameter may be reused * to store the copy of the pixels. * A new {@code Image} will be created if the supplied object is null, * is too small or of a type which the image pixels cannot be easily * converted into. * * @param bimg the {@code BufferedImage} object to be converted * @param wimg an optional {@code WritableImage} object that can be * used to store the returned pixel data * @return an {@code Image} object representing a snapshot of the * current pixels in the {@code BufferedImage}. * @since JavaFX 2.2 */ public static WritableImage toFXImage(BufferedImage bimg, WritableImage wimg) { int bw = bimg.getWidth(); int bh = bimg.getHeight(); switch (bimg.getType()) { case BufferedImage.TYPE_INT_ARGB: case BufferedImage.TYPE_INT_ARGB_PRE: break; default: BufferedImage converted = new BufferedImage(bw, bh, BufferedImage.TYPE_INT_ARGB_PRE); Graphics2D g2d = converted.createGraphics(); g2d.drawImage(bimg, 0, 0, null); g2d.dispose(); bimg = converted; break; } // assert(bimg.getType == TYPE_INT_ARGB[_PRE]); if (wimg != null) { int iw = (int) wimg.getWidth(); int ih = (int) wimg.getHeight(); if (iw < bw || ih < bh) { wimg = null; } else if (bw < iw || bh < ih) { int empty[] = new int[iw]; PixelWriter pw = wimg.getPixelWriter(); PixelFormat<IntBuffer> pf = PixelFormat.getIntArgbPreInstance(); if (bw < iw) { pw.setPixels(bw, 0, iw-bw, bh, pf, empty, 0, 0); } if (bh < ih) { pw.setPixels(0, bh, iw, ih-bh, pf, empty, 0, 0); } } } if (wimg == null) { wimg = new WritableImage(bw, bh); } PixelWriter pw = wimg.getPixelWriter(); IntegerComponentRaster icr = (IntegerComponentRaster) bimg.getRaster(); int data[] = icr.getDataStorage(); int offset = icr.getDataOffset(0); int scan = icr.getScanlineStride(); PixelFormat<IntBuffer> pf = (bimg.isAlphaPremultiplied() ? PixelFormat.getIntArgbPreInstance() : PixelFormat.getIntArgbInstance()); pw.setPixels(0, 0, bw, bh, pf, data, offset, scan); return wimg; } /** * Determine the optimal BufferedImage type to use for the specified * {@code fxFormat} allowing for the specified {@code bimg} to be used * as a potential default storage space if it is not null and is compatible. * * @param fxFormat the PixelFormat of the source FX Image * @param bimg an optional existing {@code BufferedImage} to be used * for storage if it is compatible, or null * @return */ private static int getBestBufferedImageType(PixelFormat<?> fxFormat, BufferedImage bimg) { if (bimg != null) { int bimgType = bimg.getType(); if (bimgType == BufferedImage.TYPE_INT_ARGB || bimgType == BufferedImage.TYPE_INT_ARGB_PRE) { // We will allow the caller to give us a BufferedImage // that has an alpha channel, but we might not otherwise // construct one ourselves. // We will also allow them to choose their own premultiply // type which may not match the image. // If left to our own devices we might choose a more specific // format as indicated by the choices below. return bimgType; } } switch (fxFormat.getType()) { default: case BYTE_BGRA_PRE: case INT_ARGB_PRE: return BufferedImage.TYPE_INT_ARGB_PRE; case BYTE_BGRA: case INT_ARGB: return BufferedImage.TYPE_INT_ARGB; case BYTE_RGB: return BufferedImage.TYPE_INT_RGB; case BYTE_INDEXED: return (fxFormat.isPremultiplied() ? BufferedImage.TYPE_INT_ARGB_PRE : BufferedImage.TYPE_INT_ARGB); } } /** * Determine the appropriate {@link WritablePixelFormat} type that can * be used to transfer data into the indicated BufferedImage. * * @param bimg the BufferedImage that will be used as a destination for * a {@code PixelReader<IntBuffer>#getPixels()} operation. * @return */ private static WritablePixelFormat<IntBuffer> getAssociatedPixelFormat(BufferedImage bimg) { switch (bimg.getType()) { // We lie here for xRGB, but we vetted that the src data was opaque // so we can ignore the alpha. We use ArgbPre instead of Argb // just to get a loop that does not have divides in it if the // PixelReader happens to not know the data is opaque. case BufferedImage.TYPE_INT_RGB: case BufferedImage.TYPE_INT_ARGB_PRE: return PixelFormat.getIntArgbPreInstance(); case BufferedImage.TYPE_INT_ARGB: return PixelFormat.getIntArgbInstance(); default: // Should not happen... throw new InternalError("Failed to validate BufferedImage type"); } } /** * Snapshots the specified JavaFX {@link Image} object and stores a * copy of its pixels into a {@link BufferedImage} object, creating * a new object if needed. * The method will only convert a JavaFX {@code Image} that is readable * as per the conditions on the * {@link Image#getPixelReader() Image.getPixelReader()} * method. * If the {@code Image} is not readable, as determined by its * {@code getPixelReader()} method, then this method will return null. * If the {@code Image} is a writable, or other dynamic image, then * the {@code BufferedImage} will only be set to the current state of * the pixels in the image as determined by its {@link PixelReader}. * Further changes to the pixels of the {@code Image} will not be * reflected in the returned {@code BufferedImage}. * <p> * The optional {@code BufferedImage} parameter may be reused to store * the copy of the pixels. * A new {@code BufferedImage} will be created if the supplied object * is null, is too small or of a type which the image pixels cannot * be easily converted into. * * @param img the JavaFX {@code Image} to be converted * @param bimg an optional {@code BufferedImage} object that may be * used to store the returned pixel data * @return a {@code BufferedImage} containing a snapshot of the JavaFX * {@code Image}, or null if the {@code Image} is not readable. * @since JavaFX 2.2 */ public static BufferedImage fromFXImage(Image img, BufferedImage bimg) { PixelReader pr = img.getPixelReader(); if (pr == null) { return null; } int iw = (int) img.getWidth(); int ih = (int) img.getHeight(); int prefBimgType = getBestBufferedImageType(pr.getPixelFormat(), bimg); if (bimg != null) { int bw = bimg.getWidth(); int bh = bimg.getHeight(); if (bw < iw || bh < ih || bimg.getType() != prefBimgType) { bimg = null; } else if (iw < bw || ih < bh) { Graphics2D g2d = bimg.createGraphics(); g2d.setComposite(AlphaComposite.Clear); g2d.fillRect(0, 0, bw, bh); g2d.dispose(); } } if (bimg == null) { bimg = new BufferedImage(iw, ih, prefBimgType); } IntegerComponentRaster icr = (IntegerComponentRaster) bimg.getRaster(); int offset = icr.getDataOffset(0); int scan = icr.getScanlineStride(); int data[] = icr.getDataStorage(); WritablePixelFormat<IntBuffer> pf = getAssociatedPixelFormat(bimg); pr.getPixels(0, 0, iw, ih, pf, data, offset, scan); return bimg; } /** * If called from the FX Application Thread * invokes a runnable directly blocking the calling code * Otherwise * uses Platform.runLater without blocking */ static void runOnFxThread(Runnable runnable) { if (Platform.isFxApplicationThread()) { runnable.run(); } else { Platform.runLater(runnable); } } /** * If called from the event dispatch thread * invokes a runnable directly blocking the calling code * Otherwise * uses SwingUtilities.invokeLater without blocking */ static void runOnEDT(final Runnable r) { if (SwingUtilities.isEventDispatchThread()) { r.run(); } else { SwingUtilities.invokeLater(r); } } private static final Set<Object> eventLoopKeys = new HashSet<>(); /** * The runnable is responsible for leaving the nested event loop. */ static void runOnEDTAndWait(Object nestedLoopKey, Runnable r) { Toolkit.getToolkit().checkFxUserThread(); if (SwingUtilities.isEventDispatchThread()) { r.run(); } else { eventLoopKeys.add(nestedLoopKey); SwingUtilities.invokeLater(r); Toolkit.getToolkit().enterNestedEventLoop(nestedLoopKey); } } static void leaveFXNestedLoop(Object nestedLoopKey) { if (!eventLoopKeys.contains(nestedLoopKey)) return; if (Platform.isFxApplicationThread()) { Toolkit.getToolkit().exitNestedEventLoop(nestedLoopKey, null); } else { Platform.runLater(() -> { Toolkit.getToolkit().exitNestedEventLoop(nestedLoopKey, null); }); } eventLoopKeys.remove(nestedLoopKey); } private static class FwSecondaryLoop implements SecondaryLoop { private final AtomicBoolean isRunning = new AtomicBoolean(false); @Override public boolean enter() { if (isRunning.compareAndSet(false, true)) { PlatformImpl.runAndWait(() -> { Toolkit.getToolkit().enterNestedEventLoop(FwSecondaryLoop.this); }); return true; } return false; } @Override public boolean exit() { if (isRunning.compareAndSet(true, false)) { PlatformImpl.runAndWait(() -> { Toolkit.getToolkit().exitNestedEventLoop(FwSecondaryLoop.this, null); }); return true; } return false; } } private static class FXDispatcher implements FwDispatcher { @Override public boolean isDispatchThread() { return Platform.isFxApplicationThread(); } @Override public void scheduleDispatch(Runnable runnable) { Platform.runLater(runnable); } @Override public SecondaryLoop createSecondaryLoop() { return new FwSecondaryLoop(); } } private static EventQueue getEventQueue() { return AccessController.doPrivileged( (PrivilegedAction<EventQueue>) () -> java.awt.Toolkit.getDefaultToolkit().getSystemEventQueue()); } //Called with reflection from PlatformImpl to avoid dependency private static void installFwEventQueue() { AWTAccessor.getEventQueueAccessor().setFwDispatcher(getEventQueue(), new FXDispatcher()); } //Called with reflection from PlatformImpl to avoid dependency private static void removeFwEventQueue() { AWTAccessor.getEventQueueAccessor().setFwDispatcher(getEventQueue(), null); } }
Ms-Dos/Windows
Unix
Write backup
jsp File Browser version 1.2 by
www.vonloesch.de