< prev index next >

modules/swt/src/main/java/javafx/embed/swt/FXCanvas.java

Print this page
rev 9808 : 8131888: Need to deliver javafx.swt as a modular jar in JDK 9


   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 javafx.embed.swt;
  27 












  28 import java.lang.reflect.Field;

  29 import java.nio.ByteBuffer;
  30 import java.nio.IntBuffer;
  31 import java.security.AccessController;
  32 import java.security.PrivilegedAction;
  33 import java.util.ArrayList;
  34 import java.util.Arrays;
  35 import java.util.HashMap;
  36 import java.util.HashSet;
  37 import java.util.Map;
  38 import java.util.Set;

  39 
  40 import com.sun.glass.ui.Application;
  41 import com.sun.glass.ui.Pixels;
  42 import com.sun.javafx.cursor.CursorFrame;
  43 import com.sun.javafx.cursor.CursorType;
  44 
  45 import com.sun.javafx.embed.EmbeddedSceneDSInterface;
  46 import com.sun.javafx.embed.HostDragStartListener;
  47 import javafx.application.Platform;
  48 import javafx.beans.NamedArg;
  49 import javafx.scene.Scene;
  50 import javafx.scene.input.TransferMode;

  51 
  52 import com.sun.javafx.application.PlatformImpl;
  53 import com.sun.javafx.embed.AbstractEvents;
  54 import com.sun.javafx.embed.EmbeddedSceneDTInterface;
  55 import com.sun.javafx.embed.EmbeddedSceneInterface;
  56 import com.sun.javafx.embed.EmbeddedStageInterface;
  57 import com.sun.javafx.embed.HostInterface;
  58 import com.sun.javafx.stage.EmbeddedWindow;
  59 import java.lang.reflect.Method;
  60 
  61 import org.eclipse.swt.dnd.DND;
  62 import org.eclipse.swt.dnd.DragSource;
  63 import org.eclipse.swt.dnd.DragSourceListener;
  64 import org.eclipse.swt.dnd.DropTarget;
  65 import org.eclipse.swt.dnd.DropTargetEvent;
  66 import org.eclipse.swt.dnd.DropTargetListener;
  67 import org.eclipse.swt.dnd.FileTransfer;
  68 import org.eclipse.swt.dnd.HTMLTransfer;
  69 import org.eclipse.swt.dnd.ImageTransfer;
  70 import org.eclipse.swt.dnd.RTFTransfer;
  71 import org.eclipse.swt.dnd.TextTransfer;
  72 import org.eclipse.swt.dnd.Transfer;
  73 import org.eclipse.swt.dnd.TransferData;
  74 import org.eclipse.swt.dnd.URLTransfer;
  75 import org.eclipse.swt.events.ControlEvent;

  76 import org.eclipse.swt.events.DisposeEvent;
  77 import org.eclipse.swt.events.DisposeListener;
  78 import org.eclipse.swt.events.FocusEvent;

  79 import org.eclipse.swt.events.KeyEvent;
  80 import org.eclipse.swt.events.KeyListener;
  81 import org.eclipse.swt.events.MenuDetectEvent;
  82 import org.eclipse.swt.events.MenuDetectListener;
  83 import org.eclipse.swt.events.MouseEvent;
  84 import org.eclipse.swt.events.MouseListener;
  85 import org.eclipse.swt.events.MouseMoveListener;
  86 import org.eclipse.swt.events.PaintEvent;
  87 import org.eclipse.swt.events.PaintListener;





  88 import org.eclipse.swt.widgets.Canvas;
  89 import org.eclipse.swt.widgets.Composite;
  90 import org.eclipse.swt.widgets.Control;
  91 import org.eclipse.swt.widgets.Display;
  92 import org.eclipse.swt.widgets.Event;
  93 import org.eclipse.swt.widgets.Listener;
  94 import org.eclipse.swt.widgets.Shell;
  95 import org.eclipse.swt.graphics.Image;
  96 import org.eclipse.swt.graphics.ImageData;
  97 import org.eclipse.swt.graphics.PaletteData;
  98 import org.eclipse.swt.graphics.Point;
  99 import org.eclipse.swt.graphics.Rectangle;
 100 import org.eclipse.swt.graphics.GCData;
 101 import org.eclipse.swt.graphics.GC;
 102 import org.eclipse.swt.graphics.RGB;
 103 import org.eclipse.swt.SWT;
 104 import org.eclipse.swt.events.ControlListener;
 105 import org.eclipse.swt.events.FocusListener;
 106 import org.eclipse.swt.events.MouseTrackListener;
 107 import org.eclipse.swt.events.MouseWheelListener;
 108 
 109 /**
 110  * {@code FXCanvas} is a component to embed JavaFX content into
 111  * SWT applications. The content to be displayed is specified
 112  * with the {@link #setScene} method that accepts an instance of
 113  * JavaFX {@code Scene}. After the scene is assigned, it gets
 114  * repainted automatically. All the input and focus events are
 115  * forwarded to the scene transparently to the developer.
 116  * <p>
 117  * Here is a typical pattern how {@code FXCanvas} can used:
 118  * <pre>
 119  *    public class Test {
 120  *        private static Scene createScene() {
 121  *            Group group = new Group();
 122  *            Scene scene = new Scene(group);
 123  *            Button button = new Button("JFX Button");
 124  *            group.getChildren().add(button);
 125  *            return scene;
 126  *        }
 127  *


 129  *            Display display = new Display();
 130  *            Shell shell = new Shell(display);
 131  *            shell.setLayout(new FillLayout());
 132  *            FXCanvas canvas = new FXCanvas(shell, SWT.NONE);
 133  *            Scene scene = createScene();
 134  *            canvas.setScene(scene);
 135  *            shell.open();
 136  *            while (!shell.isDisposed()) {
 137  *                if (!display.readAndDispatch()) display.sleep();
 138  *            }
 139  *            display.dispose();
 140  *        }
 141  *    }
 142  * </pre>
 143  *
 144  *
 145  * @since JavaFX 2.0
 146  */
 147 public class FXCanvas extends Canvas {
 148 




 149     private HostContainer hostContainer;
 150     private volatile EmbeddedWindow stage;
 151     private volatile Scene scene;
 152     private EmbeddedStageInterface stagePeer;
 153     private EmbeddedSceneInterface scenePeer;
 154 
 155     private int pWidth = 0;
 156     private int pHeight = 0;
 157 
 158     private volatile int pPreferredWidth = -1;
 159     private volatile int pPreferredHeight = -1;
 160 
 161     private IntBuffer pixelsBuf = null;
 162 
 163     // This filter runs when any widget is moved
 164     Listener moveFilter = event -> {
 165         // If a parent has moved, send a move event to FX
 166         Control control = FXCanvas.this;
 167         while (control != null) {
 168             if (control == event.widget) {


 232         if (SWT.getPlatform().equals("cocoa")) {
 233             try {
 234                 windowField = Shell.class.getDeclaredField("window");
 235                 windowField.setAccessible(true);
 236 
 237                 Class nsViewClass = Class.forName("org.eclipse.swt.internal.cocoa.NSView");
 238                 windowMethod = nsViewClass.getDeclaredMethod("window");
 239                 windowMethod.setAccessible(true);
 240 
 241                 Class nsWindowClass = Class.forName("org.eclipse.swt.internal.cocoa.NSWindow");
 242                 screenMethod = nsWindowClass.getDeclaredMethod("screen");
 243                 screenMethod.setAccessible(true);
 244 
 245                 Class nsScreenClass = Class.forName("org.eclipse.swt.internal.cocoa.NSScreen");
 246                 backingScaleFactorMethod = nsScreenClass.getDeclaredMethod("backingScaleFactor");
 247                 backingScaleFactorMethod.setAccessible(true);
 248             } catch (Exception e) {
 249                 //Fail silently.  If we can't get the methods, then the current version of SWT has no retina support
 250             }
 251         }


 252     }
 253 
 254     /**
 255      * @inheritDoc
 256      */
 257     public FXCanvas(@NamedArg("parent") Composite parent, @NamedArg("style") int style) {
 258         super(parent, style | SWT.NO_BACKGROUND);
 259         initFx();
 260         hostContainer = new HostContainer();
 261         registerEventListeners();
 262         Display display = parent.getDisplay();
 263         display.addFilter(SWT.Move, moveFilter);
 264     }
 265 
 266     private static void initFx() {
 267         AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
 268             System.setProperty("javafx.embed.isEventThread", "true");
 269             System.setProperty("glass.win.uiScale", "100%");
 270             System.setProperty("glass.win.renderScale", "100%");
 271             return null;
 272         });
 273         Map map = Application.getDeviceDetails();
 274         if (map == null) {
 275             Application.setDeviceDetails(map = new HashMap());
 276         }
 277         if (map.get("javafx.embed.eventProc") == null) {
 278             long eventProc = 0;
 279             try {
 280                 Field field = Display.class.getDeclaredField("eventProc");
 281                 field.setAccessible(true);
 282                 if (field.getType() == int.class) {
 283                     eventProc = field.getLong(Display.getDefault());
 284                 } else {
 285                     if (field.getType() == long.class) {
 286                         eventProc = field.getLong(Display.getDefault());
 287                     }
 288                 }
 289             } catch (Throwable th) {
 290                 //Fail silently
 291             }
 292             map.put("javafx.embed.eventProc", eventProc);
 293         }
 294         // Note that calling PlatformImpl.startup more than once is OK
 295         PlatformImpl.startup(() -> {
 296             Application.GetApplication().setName(Display.getAppName());




 297         });



















 298     }
 299 
 300     static ArrayList<DropTarget> targets = new ArrayList<>();
 301 
 302     DropTarget getDropTarget() {
 303         return dropTarget;
 304     }
 305 
 306     void setDropTarget(DropTarget newTarget) {
 307         if (dropTarget != null) {
 308             targets.remove(dropTarget);
 309             dropTarget.dispose();
 310         }
 311         dropTarget = newTarget;
 312         if (dropTarget != null) {
 313             targets.add(dropTarget);
 314         }
 315     }
 316 
 317     static void updateDropTarget() {




   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 javafx.embed.swt;
  27 
  28 import com.sun.glass.ui.Application;
  29 import com.sun.glass.ui.Pixels;
  30 import com.sun.javafx.cursor.CursorFrame;
  31 import com.sun.javafx.cursor.CursorType;
  32 import com.sun.javafx.embed.AbstractEvents;
  33 import com.sun.javafx.embed.EmbeddedSceneDSInterface;
  34 import com.sun.javafx.embed.EmbeddedSceneDTInterface;
  35 import com.sun.javafx.embed.EmbeddedSceneInterface;
  36 import com.sun.javafx.embed.EmbeddedStageInterface;
  37 import com.sun.javafx.embed.HostInterface;
  38 import com.sun.javafx.stage.EmbeddedWindow;
  39 
  40 import java.lang.reflect.Field;
  41 import java.lang.reflect.Method;
  42 import java.nio.ByteBuffer;
  43 import java.nio.IntBuffer;
  44 import java.security.AccessController;
  45 import java.security.PrivilegedAction;
  46 import java.util.ArrayList;
  47 import java.util.Arrays;

  48 import java.util.HashSet;

  49 import java.util.Set;
  50 import java.util.concurrent.CountDownLatch;
  51 







  52 import javafx.application.Platform;
  53 import javafx.beans.NamedArg;
  54 import javafx.scene.Scene;
  55 import javafx.scene.input.TransferMode;
  56 import javafx.util.FXPermission;
  57 
  58 import org.eclipse.swt.SWT;








  59 import org.eclipse.swt.dnd.DND;
  60 import org.eclipse.swt.dnd.DragSource;
  61 import org.eclipse.swt.dnd.DragSourceListener;
  62 import org.eclipse.swt.dnd.DropTarget;
  63 import org.eclipse.swt.dnd.DropTargetEvent;
  64 import org.eclipse.swt.dnd.DropTargetListener;
  65 import org.eclipse.swt.dnd.FileTransfer;
  66 import org.eclipse.swt.dnd.HTMLTransfer;
  67 import org.eclipse.swt.dnd.ImageTransfer;
  68 import org.eclipse.swt.dnd.RTFTransfer;
  69 import org.eclipse.swt.dnd.TextTransfer;
  70 import org.eclipse.swt.dnd.Transfer;
  71 import org.eclipse.swt.dnd.TransferData;
  72 import org.eclipse.swt.dnd.URLTransfer;
  73 import org.eclipse.swt.events.ControlEvent;
  74 import org.eclipse.swt.events.ControlListener;
  75 import org.eclipse.swt.events.DisposeEvent;
  76 import org.eclipse.swt.events.DisposeListener;
  77 import org.eclipse.swt.events.FocusEvent;
  78 import org.eclipse.swt.events.FocusListener;
  79 import org.eclipse.swt.events.KeyEvent;
  80 import org.eclipse.swt.events.KeyListener;
  81 import org.eclipse.swt.events.MenuDetectEvent;

  82 import org.eclipse.swt.events.MouseEvent;
  83 import org.eclipse.swt.events.MouseListener;
  84 import org.eclipse.swt.events.MouseTrackListener;
  85 import org.eclipse.swt.events.PaintEvent;
  86 import org.eclipse.swt.graphics.Image;
  87 import org.eclipse.swt.graphics.ImageData;
  88 import org.eclipse.swt.graphics.PaletteData;
  89 import org.eclipse.swt.graphics.Point;
  90 import org.eclipse.swt.graphics.RGB;
  91 import org.eclipse.swt.graphics.Rectangle;
  92 import org.eclipse.swt.widgets.Canvas;
  93 import org.eclipse.swt.widgets.Composite;
  94 import org.eclipse.swt.widgets.Control;
  95 import org.eclipse.swt.widgets.Display;

  96 import org.eclipse.swt.widgets.Listener;
  97 import org.eclipse.swt.widgets.Shell;













  98 
  99 /**
 100  * {@code FXCanvas} is a component to embed JavaFX content into
 101  * SWT applications. The content to be displayed is specified
 102  * with the {@link #setScene} method that accepts an instance of
 103  * JavaFX {@code Scene}. After the scene is assigned, it gets
 104  * repainted automatically. All the input and focus events are
 105  * forwarded to the scene transparently to the developer.
 106  * <p>
 107  * Here is a typical pattern how {@code FXCanvas} can used:
 108  * <pre>
 109  *    public class Test {
 110  *        private static Scene createScene() {
 111  *            Group group = new Group();
 112  *            Scene scene = new Scene(group);
 113  *            Button button = new Button("JFX Button");
 114  *            group.getChildren().add(button);
 115  *            return scene;
 116  *        }
 117  *


 119  *            Display display = new Display();
 120  *            Shell shell = new Shell(display);
 121  *            shell.setLayout(new FillLayout());
 122  *            FXCanvas canvas = new FXCanvas(shell, SWT.NONE);
 123  *            Scene scene = createScene();
 124  *            canvas.setScene(scene);
 125  *            shell.open();
 126  *            while (!shell.isDisposed()) {
 127  *                if (!display.readAndDispatch()) display.sleep();
 128  *            }
 129  *            display.dispose();
 130  *        }
 131  *    }
 132  * </pre>
 133  *
 134  *
 135  * @since JavaFX 2.0
 136  */
 137 public class FXCanvas extends Canvas {
 138 
 139     // Internal permission used by FXCanvas (SWT interop)
 140     private static final FXPermission FXCANVAS_PERMISSION =
 141             new FXPermission("accessFXCanvasInternals");
 142 
 143     private HostContainer hostContainer;
 144     private volatile EmbeddedWindow stage;
 145     private volatile Scene scene;
 146     private EmbeddedStageInterface stagePeer;
 147     private EmbeddedSceneInterface scenePeer;
 148 
 149     private int pWidth = 0;
 150     private int pHeight = 0;
 151 
 152     private volatile int pPreferredWidth = -1;
 153     private volatile int pPreferredHeight = -1;
 154 
 155     private IntBuffer pixelsBuf = null;
 156 
 157     // This filter runs when any widget is moved
 158     Listener moveFilter = event -> {
 159         // If a parent has moved, send a move event to FX
 160         Control control = FXCanvas.this;
 161         while (control != null) {
 162             if (control == event.widget) {


 226         if (SWT.getPlatform().equals("cocoa")) {
 227             try {
 228                 windowField = Shell.class.getDeclaredField("window");
 229                 windowField.setAccessible(true);
 230 
 231                 Class nsViewClass = Class.forName("org.eclipse.swt.internal.cocoa.NSView");
 232                 windowMethod = nsViewClass.getDeclaredMethod("window");
 233                 windowMethod.setAccessible(true);
 234 
 235                 Class nsWindowClass = Class.forName("org.eclipse.swt.internal.cocoa.NSWindow");
 236                 screenMethod = nsWindowClass.getDeclaredMethod("screen");
 237                 screenMethod.setAccessible(true);
 238 
 239                 Class nsScreenClass = Class.forName("org.eclipse.swt.internal.cocoa.NSScreen");
 240                 backingScaleFactorMethod = nsScreenClass.getDeclaredMethod("backingScaleFactor");
 241                 backingScaleFactorMethod.setAccessible(true);
 242             } catch (Exception e) {
 243                 //Fail silently.  If we can't get the methods, then the current version of SWT has no retina support
 244             }
 245         }
 246         initFx();
 247         System.err.println("FXCanvas class successfully initialized");
 248     }
 249 
 250     /**
 251      * @inheritDoc
 252      */
 253     public FXCanvas(@NamedArg("parent") Composite parent, @NamedArg("style") int style) {
 254         super(parent, style | SWT.NO_BACKGROUND);
 255         setApplicationName(Display.getAppName());
 256         hostContainer = new HostContainer();
 257         registerEventListeners();
 258         Display display = parent.getDisplay();
 259         display.addFilter(SWT.Move, moveFilter);
 260     }
 261 
 262     private static void initFx() {
 263         // NOTE: no internal "com.sun.*" packages can be accessed until after
 264         // the JavaFX platform is initialized. The list of needed internal
 265         // packages is kept in the PlatformImpl class.








 266         long eventProc = 0;
 267         try {
 268             Field field = Display.class.getDeclaredField("eventProc");
 269             field.setAccessible(true);
 270             if (field.getType() == int.class) {
 271                 eventProc = field.getInt(Display.getDefault());
 272             } else {
 273                 if (field.getType() == long.class) {
 274                     eventProc = field.getLong(Display.getDefault());
 275                 }
 276             }
 277         } catch (Throwable th) {
 278             //Fail silently
 279         }
 280         final String eventProcStr = String.valueOf(eventProc);
 281 
 282         AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
 283             System.setProperty("com.sun.javafx.application.type", "FXCanvas");
 284             System.setProperty("javafx.embed.isEventThread", "true");
 285             System.setProperty("glass.win.uiScale", "100%");
 286             System.setProperty("glass.win.renderScale", "100%");
 287             System.setProperty("javafx.embed.eventProc", eventProcStr);
 288             return null;
 289         });
 290 
 291         final CountDownLatch startupLatch = new CountDownLatch(1);
 292         AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
 293             Platform.startup(() -> {
 294                 System.err.println("FXCanvas: FX platform is initlialized");
 295                 startupLatch.countDown();
 296             });
 297             return null;
 298         }, null, FXCANVAS_PERMISSION);
 299 
 300         try {
 301             startupLatch.await();
 302         } catch (InterruptedException ex) {
 303             throw new RuntimeException(ex);
 304         }
 305     }
 306 
 307     private void setApplicationName(String name) {
 308         Platform.runLater(()-> Application.GetApplication().setName(name));
 309     }
 310 
 311     static ArrayList<DropTarget> targets = new ArrayList<>();
 312 
 313     DropTarget getDropTarget() {
 314         return dropTarget;
 315     }
 316 
 317     void setDropTarget(DropTarget newTarget) {
 318         if (dropTarget != null) {
 319             targets.remove(dropTarget);
 320             dropTarget.dispose();
 321         }
 322         dropTarget = newTarget;
 323         if (dropTarget != null) {
 324             targets.add(dropTarget);
 325         }
 326     }
 327 
 328     static void updateDropTarget() {


< prev index next >