--- old/modules/javafx.swing/src/main/java/javafx/embed/swing/SwingNode.java 2018-07-09 16:35:35.811591400 +0530 +++ new/modules/javafx.swing/src/main/java/javafx/embed/swing/SwingNode.java 2018-07-09 16:35:35.004988900 +0530 @@ -53,7 +53,6 @@ import java.awt.dnd.DragSource; import java.awt.dnd.DropTarget; import java.awt.dnd.InvalidDnDOperationException; -import java.awt.dnd.peer.DragSourceContextPeer; import java.awt.event.InputEvent; import java.awt.event.MouseWheelEvent; import java.awt.event.WindowEvent; @@ -80,12 +79,14 @@ import com.sun.javafx.PlatformUtil; import com.sun.javafx.embed.swing.SwingNodeHelper; import com.sun.javafx.scene.NodeHelper; -import sun.awt.UngrabEvent; -import sun.swing.JLightweightFrame; -import sun.swing.LightweightContent; +import com.sun.javafx.embed.swing.SwingEvents; +import com.sun.javafx.embed.swing.SwingCursors; import static javafx.stage.WindowEvent.WINDOW_HIDDEN; +import com.sun.javafx.embed.swing.InteropFactory; +import com.sun.javafx.embed.swing.SwingNodeInterop; + /** * This class is used to embed a Swing content into a JavaFX application. * The content to be displayed is specified with the {@link #setContent} method @@ -129,8 +130,17 @@ */ public class SwingNode extends Node { private static boolean isThreadMerged; + private static SwingNodeInterop swiop; static { + InteropFactory instance = null; + try { + instance = InteropFactory.getInstance(); + } catch (Exception e) { + throw new ExceptionInInitializerError(e); + } + swiop = instance.createSwingNodeImpl(); + AccessController.doPrivileged(new PrivilegedAction() { public Object run() { isThreadMerged = Boolean.valueOf( @@ -139,6 +149,7 @@ } }); + // This is used by classes in different packages to get access to // private and package private methods. SwingNodeHelper.setSwingNodeAccessor(new SwingNodeHelper.SwingNodeAccessor() { @@ -162,12 +173,81 @@ public boolean doComputeContains(Node node, double localX, double localY) { return ((SwingNode) node).doComputeContains(localX, localY); } + + @Override + public Object getLightweightFrame(SwingNode node) { + return node.getLightweightFrame(); + } + + @Override + public ReentrantLock getPaintLock(SwingNode node) { + return node.getPaintLock(); + } + + @Override + public void setImageBuffer(SwingNode node, final int[] data, + final int x, final int y, + final int w, final int h, final int linestride, + final double scaleX, final double scaleY) { + node.setImageBuffer(data, x, y, w, h, linestride, scaleX, scaleY); + } + + @Override + public void setImageBounds(SwingNode node, final int x, final int y, + final int w, final int h) { + node.setImageBounds(x, y, w, h); + } + + @Override + public void repaintDirtyRegion(SwingNode node, final int dirtyX, final int dirtyY, + final int dirtyWidth, final int dirtyHeight) { + node.repaintDirtyRegion(dirtyX, dirtyY, dirtyWidth, dirtyHeight); + } + + @Override + public void ungrabFocus(SwingNode node, boolean postUngrabEvent) { + node.ungrabFocus(postUngrabEvent); + } + + @Override + public void setSwingPrefWidth(SwingNode node, int swingPrefWidth) { + node.swingPrefWidth = swingPrefWidth; + } + + @Override + public void setSwingPrefHeight(SwingNode node, int swingPrefHeight) { + node.swingPrefHeight = swingPrefHeight; + } + + @Override + public void setSwingMaxWidth(SwingNode node, int swingMaxWidth) { + node.swingMaxWidth = swingMaxWidth; + } + + @Override + public void setSwingMaxHeight(SwingNode node, int swingMaxHeight) { + node.swingMaxHeight = swingMaxHeight; + } + + @Override + public void setSwingMinWidth(SwingNode node, int swingMinWidth) { + node.swingMinWidth = swingMinWidth; + } + + @Override + public void setSwingMinHeight(SwingNode node, int swingMinHeight) { + node.swingMinHeight = swingMinHeight; + } + + @Override + public void setGrabbed(SwingNode node, boolean grab) { + node.grabbed = grab; + } }); } private double fxWidth; private double fxHeight; - private int swingPrefWidth; private int swingPrefHeight; private int swingMaxWidth; @@ -176,16 +256,19 @@ private int swingMinHeight; private volatile JComponent content; - private volatile JLightweightFrame lwFrame; - final JLightweightFrame getLightweightFrame() { return lwFrame; } + private volatile Object lwFrame; + private final Object getLightweightFrame() { return lwFrame; } private NGExternalNode peer; private final ReentrantLock paintLock = new ReentrantLock(); + private ReentrantLock getPaintLock() { + return paintLock; + } + private boolean skipBackwardUnrgabNotification; private boolean grabbed; // lwframe initiated grab - private Timer deactivate; // lwFrame deactivate delay for Linux { // To initialize the class helper at the begining each constructor of this class @@ -202,7 +285,7 @@ setEventHandler(ScrollEvent.SCROLL, new SwingScrollEventHandler()); focusedProperty().addListener((observable, oldValue, newValue) -> { - activateLwFrame(newValue); + swiop.activateLwFrame(lwFrame, newValue); }); //Workaround for RT-34170 @@ -216,14 +299,14 @@ TKStage tk = WindowHelper.getPeer(w); if (tk != null) { if (isThreadMerged) { - jlfOverrideNativeWindowHandle.invoke(lwFrame, 0L, null); + swiop.overrideNativeWindowHandle(0L, null); } else { // Postpone actual window closing to ensure that // a native window handler is valid on a Swing side tk.postponeClose(); - SwingFXUtils.runOnEDT(() -> { - jlfOverrideNativeWindowHandle.invoke(lwFrame, 0L, - (Runnable) () -> SwingFXUtils.runOnFxThread( + SwingNodeHelper.runOnEDT(() -> { + swiop.overrideNativeWindowHandle(0L, + (Runnable) () -> SwingNodeHelper.runOnFxThread( () -> tk.closePostponed())); }); } @@ -252,7 +335,7 @@ rawHandle = tkStage.getRawHandle(); } } - jlfOverrideNativeWindowHandle.invoke(lwFrame, rawHandle, null); + swiop.overrideNativeWindowHandle(rawHandle, null); } } @@ -271,7 +354,7 @@ public void setContent(final JComponent content) { this.content = content; - SwingFXUtils.runOnEDT(() -> setContentImpl(content)); + SwingNodeHelper.runOnEDT(() -> setContentImpl(content)); } /** @@ -330,69 +413,41 @@ } } - /** - * Calls JLightweightFrame.notifyDisplayChanged. - * Must be called on EDT only. - */ - private static OptionalMethod jlfNotifyDisplayChanged; - private static OptionalMethod jlfOverrideNativeWindowHandle; - - static { - jlfNotifyDisplayChanged = new OptionalMethod<>(JLightweightFrame.class, - "notifyDisplayChanged", Double.TYPE, Double.TYPE); - if (!jlfNotifyDisplayChanged.isSupported()) { - jlfNotifyDisplayChanged = new OptionalMethod<>( - JLightweightFrame.class,"notifyDisplayChanged", Integer.TYPE); - } - - jlfOverrideNativeWindowHandle = new OptionalMethod<>(JLightweightFrame.class, - "overrideNativeWindowHandle", Long.TYPE, Runnable.class); - - } - /* * Called on EDT */ private void setContentImpl(JComponent content) { if (lwFrame != null) { - lwFrame.dispose(); + swiop.disposeLwFrame(); lwFrame = null; } if (content != null) { - lwFrame = new JLightweightFrame(); + lwFrame = swiop.createLightweightFrame(); SwingNodeWindowFocusListener snfListener = new SwingNodeWindowFocusListener(this); - lwFrame.addWindowFocusListener(snfListener); + swiop.addWindowFocusListener(lwFrame, snfListener); if (getScene() != null) { Window window = getScene().getWindow(); if (window != null) { - if (jlfNotifyDisplayChanged.isIntegerApi()) { - jlfNotifyDisplayChanged.invoke(lwFrame, - (int) Math.round(window.getRenderScaleX())); - } else { - jlfNotifyDisplayChanged.invoke(lwFrame, - window.getRenderScaleX(), - window.getRenderScaleY()); - } + swiop.notifyDisplayChanged(lwFrame, window); } } - lwFrame.setContent(new SwingNodeContent(content, this)); - lwFrame.setVisible(true); + swiop.setContent(lwFrame, swiop.createSwingNodeContent(content, this)); + swiop.setVisible(lwFrame, true); - SwingNodeDisposer disposeRec = new SwingNodeDisposer(lwFrame); - Disposer.addRecord(this, disposeRec); + Disposer.addRecord(this, swiop.createSwingNodeDisposer(lwFrame)); if (getScene() != null) { notifyNativeHandle(getScene().getWindow()); } - SwingFXUtils.runOnFxThread(() -> { - locateLwFrame(); // initialize location + SwingNodeHelper.runOnFxThread(() -> { + locateLwFrame();// initialize location if (focusedProperty().get()) { - activateLwFrame(true); + swiop.activateLwFrame(lwFrame, true); } }); } @@ -412,7 +467,7 @@ { Runnable r = () -> peer.setImageBuffer(IntBuffer.wrap(data), x, y, w, h, w, h, linestride, scaleX, scaleY); - SwingFXUtils.runOnFxThread(() -> { + SwingNodeHelper.runOnFxThread(() -> { if (peer != null) { r.run(); } else { @@ -427,7 +482,7 @@ */ void setImageBounds(final int x, final int y, final int w, final int h) { Runnable r = () -> peer.setImageBounds(x, y, w, h, w, h); - SwingFXUtils.runOnFxThread(() -> { + SwingNodeHelper.runOnFxThread(() -> { if (peer != null) { r.run(); } else { @@ -444,7 +499,7 @@ peer.repaintDirtyRegion(dirtyX, dirtyY, dirtyWidth, dirtyHeight); NodeHelper.markDirty(this, DirtyBits.NODE_CONTENTS); }; - SwingFXUtils.runOnFxThread(() -> { + SwingNodeHelper.runOnFxThread(() -> { if (peer != null) { r.run(); } else { @@ -475,7 +530,7 @@ this.fxHeight = height; NodeHelper.geomChanged(this); NodeHelper.markDirty(this, DirtyBits.NODE_GEOMETRY); - SwingFXUtils.runOnEDT(() -> { + SwingNodeHelper.runOnEDT(() -> { if (lwFrame != null) { locateLwFrame(); } @@ -559,14 +614,15 @@ private final EventHandler ungrabHandler = event -> { if (!skipBackwardUnrgabNotification) { if (lwFrame != null) { - AccessController.doPrivileged(new PostEventAction(new UngrabEvent(lwFrame))); + AccessController.doPrivileged(new PostEventAction( + swiop.createUngrabEvent(lwFrame))); } } }; private final ChangeListener windowVisibleListener = (observable, oldValue, newValue) -> { if (!newValue) { - disposeLwFrame(); + swiop.disposeLwFrame(); } else { setContent(content); } @@ -609,7 +665,7 @@ window.renderScaleXProperty().addListener(locationListener); window.addEventHandler(FocusUngrabEvent.FOCUS_UNGRAB, ungrabHandler); window.showingProperty().addListener(windowVisibleListener); - setLwFrameScale(window.getRenderScaleX(), window.getRenderScaleY()); + swiop.setLwFrameScale(window.getRenderScaleX(), window.getRenderScaleY()); } private void removeWindowListeners(final Window window) { @@ -641,7 +697,7 @@ if (oldValue != null) { // Removed from scene removeSceneListeners(oldValue); - disposeLwFrame(); + swiop.disposeLwFrame(); } if (newValue != null) { // Added to another scene @@ -653,7 +709,7 @@ }); NodeHelper.treeVisibleProperty(this).addListener((observable, oldValue, newValue) -> { - setLwFrameVisible(newValue); + swiop.setLwFrameVisible(newValue); }); return peer; @@ -672,14 +728,6 @@ } } - /** - * Calls JLightweightFrame.setHostBounds. - * Must be called on EDT only. - */ - private static final OptionalMethod jlfSetHostBounds = - new OptionalMethod<>(JLightweightFrame.class, "setHostBounds", - Integer.TYPE, Integer.TYPE, Integer.TYPE, Integer.TYPE); - private void locateLwFrame() { if (getScene() == null || lwFrame == null @@ -701,88 +749,11 @@ final int frameW = (int) (fxWidth); final int frameH = (int) (fxHeight); - SwingFXUtils.runOnEDT(() -> { - if (lwFrame != null) { - if (jlfNotifyDisplayChanged.isIntegerApi()) { - jlfNotifyDisplayChanged.invoke(lwFrame, - (int)Math.round(renderScaleX)); - } else { - jlfNotifyDisplayChanged.invoke(lwFrame, renderScaleX, - renderScaleY); - } - lwFrame.setBounds(frameX, frameY, frameW, frameH); - jlfSetHostBounds.invoke(lwFrame, windowX, windowY, - windowW, windowH); - } - }); - } - - private void activateLwFrame(final boolean activate) { - if (lwFrame == null) { - return; - } - if (PlatformUtil.isLinux()) { - // Workaround to block FocusOut/FocusIn notifications from Unity - // focus grabbing upon Alt press - if (deactivate == null || !deactivate.isRunning()) { - if (!activate) { - deactivate = new Timer(50, (e) -> { - { - if (lwFrame != null) { - lwFrame.emulateActivation(false); - } - } - }); - deactivate.start(); - return; - } - } else { - deactivate.stop(); - } - } - - SwingFXUtils.runOnEDT(() -> { - if (lwFrame != null) { - lwFrame.emulateActivation(activate); - } - }); - } - - private void disposeLwFrame() { - if (lwFrame == null) { - return; - } - SwingFXUtils.runOnEDT(() -> { - if (lwFrame != null) { - lwFrame.dispose(); - lwFrame = null; - } - }); - } - - private void setLwFrameVisible(final boolean visible) { - if (lwFrame == null) { - return; - } - SwingFXUtils.runOnEDT(() -> { - if (lwFrame != null) { - lwFrame.setVisible(visible); - } - }); - } - - private void setLwFrameScale(final double scaleX, final double scaleY) { - if (lwFrame == null) { - return; - } - SwingFXUtils.runOnEDT(() -> { + SwingNodeHelper.runOnEDT(() -> { if (lwFrame != null) { - if (jlfNotifyDisplayChanged.isIntegerApi()) { - jlfNotifyDisplayChanged.invoke(lwFrame, - (int)Math.round(scaleX)); - } else { - jlfNotifyDisplayChanged.invoke(lwFrame, scaleX, scaleY); - } + swiop.notifyDisplayChanged(lwFrame, w); + swiop.setBounds(lwFrame, frameX, frameY, frameW, frameH); + swiop.setHostBounds(lwFrame, w); } }); } @@ -796,19 +767,6 @@ return bounds; } - private static class SwingNodeDisposer implements DisposerRecord { - JLightweightFrame lwFrame; - - SwingNodeDisposer(JLightweightFrame ref) { - this.lwFrame = ref; - } - public void dispose() { - if (lwFrame != null) { - lwFrame.dispose(); - lwFrame = null; - } - } - } private static class SwingNodeWindowFocusListener implements WindowFocusListener { private WeakReference swingNodeRef; @@ -819,7 +777,7 @@ @Override public void windowGainedFocus(WindowEvent e) { - SwingFXUtils.runOnFxThread(() -> { + SwingNodeHelper.runOnFxThread(() -> { SwingNode swingNode = swingNodeRef.get(); if (swingNode != null) { swingNode.requestFocus(); @@ -829,7 +787,7 @@ @Override public void windowLostFocus(WindowEvent e) { - SwingFXUtils.runOnFxThread(() -> { + SwingNodeHelper.runOnFxThread(() -> { SwingNode swingNode = swingNodeRef.get(); if (swingNode != null) { swingNode.ungrabFocus(true); @@ -838,182 +796,6 @@ } } - private static class SwingNodeContent implements LightweightContent { - private JComponent comp; - private volatile FXDnD dnd; - private WeakReference swingNodeRef; - - SwingNodeContent(JComponent comp, SwingNode swingNode) { - this.comp = comp; - this.swingNodeRef = new WeakReference(swingNode); - } - @Override - public JComponent getComponent() { - return comp; - } - @Override - public void paintLock() { - SwingNode swingNode = swingNodeRef.get(); - if (swingNode != null) { - swingNode.paintLock.lock(); - } - } - @Override - public void paintUnlock() { - SwingNode swingNode = swingNodeRef.get(); - if (swingNode != null) { - swingNode.paintLock.unlock(); - } - } - - // Note: we skip @Override annotation and implement both pre-hiDPI and post-hiDPI versions - // of the method for compatibility. - //@Override - public void imageBufferReset(int[] data, int x, int y, int width, int height, int linestride) { - imageBufferReset(data, x, y, width, height, linestride, 1); - } - //@Override - public void imageBufferReset(int[] data, int x, int y, int width, int height, int linestride, int scale) { - SwingNode swingNode = swingNodeRef.get(); - if (swingNode != null) { - swingNode.setImageBuffer(data, x, y, width, height, linestride, scale, scale); - } - } - //@Override - public void imageBufferReset(int[] data, int x, int y, int width, int height, int linestride, double scaleX, double scaleY) { - SwingNode swingNode = swingNodeRef.get(); - if (swingNode != null) { - swingNode.setImageBuffer(data, x, y, width, height, linestride, scaleX, scaleY); - } - } - @Override - public void imageReshaped(int x, int y, int width, int height) { - SwingNode swingNode = swingNodeRef.get(); - if (swingNode != null) { - swingNode.setImageBounds(x, y, width, height); - } - } - @Override - public void imageUpdated(int dirtyX, int dirtyY, int dirtyWidth, int dirtyHeight) { - SwingNode swingNode = swingNodeRef.get(); - if (swingNode != null) { - swingNode.repaintDirtyRegion(dirtyX, dirtyY, dirtyWidth, dirtyHeight); - } - } - @Override - public void focusGrabbed() { - SwingFXUtils.runOnFxThread(() -> { - // On X11 grab is limited to a single XDisplay connection, - // so we can't delegate it to another GUI toolkit. - if (PlatformUtil.isLinux()) return; - - SwingNode swingNode = swingNodeRef.get(); - if (swingNode != null) { - Scene scene = swingNode.getScene(); - if (scene != null && - scene.getWindow() != null && - WindowHelper.getPeer(scene.getWindow()) != null) { - WindowHelper.getPeer(scene.getWindow()).grabFocus(); - swingNode.grabbed = true; - } - } - }); - } - @Override - public void focusUngrabbed() { - SwingFXUtils.runOnFxThread(() -> { - SwingNode swingNode = swingNodeRef.get(); - if (swingNode != null) { - swingNode.ungrabFocus(false); - } - }); - } - @Override - public void preferredSizeChanged(final int width, final int height) { - SwingFXUtils.runOnFxThread(() -> { - SwingNode swingNode = swingNodeRef.get(); - if (swingNode != null) { - swingNode.swingPrefWidth = width; - swingNode.swingPrefHeight = height; - NodeHelper.notifyLayoutBoundsChanged(swingNode); - } - }); - } - @Override - public void maximumSizeChanged(final int width, final int height) { - SwingFXUtils.runOnFxThread(() -> { - SwingNode swingNode = swingNodeRef.get(); - if (swingNode != null) { - swingNode.swingMaxWidth = width; - swingNode.swingMaxHeight = height; - NodeHelper.notifyLayoutBoundsChanged(swingNode); - } - }); - } - @Override - public void minimumSizeChanged(final int width, final int height) { - SwingFXUtils.runOnFxThread(() -> { - SwingNode swingNode = swingNodeRef.get(); - if (swingNode != null) { - swingNode.swingMinWidth = width; - swingNode.swingMinHeight = height; - NodeHelper.notifyLayoutBoundsChanged(swingNode); - } - }); - } - - //@Override - public void setCursor(Cursor cursor) { - SwingFXUtils.runOnFxThread(() -> { - SwingNode swingNode = swingNodeRef.get(); - if (swingNode != null) { - swingNode.setCursor(SwingCursors.embedCursorToCursor(cursor)); - } - }); - } - - private void initDnD() { - // This is a part of AWT API, so the method may be invoked on any thread - synchronized (SwingNodeContent.this) { - if (this.dnd == null) { - SwingNode swingNode = swingNodeRef.get(); - if (swingNode != null) { - this.dnd = new FXDnD(swingNode); - } - } - } - } - - //@Override - public synchronized T createDragGestureRecognizer( - Class abstractRecognizerClass, - DragSource ds, Component c, int srcActions, - DragGestureListener dgl) - { - initDnD(); - return dnd.createDragGestureRecognizer(abstractRecognizerClass, ds, c, srcActions, dgl); - } - - //@Override - public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge) throws InvalidDnDOperationException - { - initDnD(); - return dnd.createDragSourceContextPeer(dge); - } - - //@Override - public void addDropTarget(DropTarget dt) { - initDnD(); - dnd.addDropTarget(dt); - } - - //@Override - public void removeDropTarget(DropTarget dt) { - initDnD(); - dnd.removeDropTarget(dt); - } - } - private void ungrabFocus(boolean postUngrabEvent) { // On X11 grab is limited to a single XDisplay connection, // so we can't delegate it to another GUI toolkit. @@ -1049,7 +831,7 @@ @Override public void handle(MouseEvent event) { - JLightweightFrame frame = lwFrame; + Object frame = swiop.getLightweightFrame(); if (frame == null) { return; } @@ -1087,7 +869,7 @@ int absX = (int) Math.round(event.getScreenX()); int absY = (int) Math.round(event.getScreenY()); java.awt.event.MouseEvent mouseEvent = - new java.awt.event.MouseEvent( + swiop.createMouseEvent( frame, swingID, swingWhen, swingModifiers, relX, relY, absX, absY, event.getClickCount(), swingPopupTrigger, swingButton); @@ -1098,7 +880,7 @@ private class SwingScrollEventHandler implements EventHandler { @Override public void handle(ScrollEvent event) { - JLightweightFrame frame = lwFrame; + Object frame = swiop.getLightweightFrame(); if (frame == null) { return; } @@ -1122,7 +904,7 @@ } } - private void sendMouseWheelEvent(Component source, double fxX, double fxY, int swingModifiers, double delta) { + private void sendMouseWheelEvent(Object source, double fxX, double fxY, int swingModifiers, double delta) { int wheelRotation = (int) delta; int signum = (int) Math.signum(delta); if (signum * delta < 1) { @@ -1131,9 +913,7 @@ int x = (int) Math.round(fxX); int y = (int) Math.round(fxY); MouseWheelEvent mouseWheelEvent = - new MouseWheelEvent(source, java.awt.event.MouseEvent.MOUSE_WHEEL, - System.currentTimeMillis(), swingModifiers, x, y, 0, 0, - 0, false, MouseWheelEvent.WHEEL_UNIT_SCROLL, 1 , -wheelRotation); + swiop.createMouseWheelEvent(source, swingModifiers, x, y, -wheelRotation); AccessController.doPrivileged(new PostEventAction(mouseWheelEvent)); } } @@ -1141,7 +921,7 @@ private class SwingKeyEventHandler implements EventHandler { @Override public void handle(KeyEvent event) { - JLightweightFrame frame = lwFrame; + Object frame = swiop.getLightweightFrame(); if (frame == null) { return; } @@ -1176,10 +956,11 @@ } } long swingWhen = System.currentTimeMillis(); - java.awt.event.KeyEvent keyEvent = new java.awt.event.KeyEvent( - frame, swingID, swingWhen, swingModifiers, - swingKeyCode, swingChar); + java.awt.event.KeyEvent keyEvent = swiop.createKeyEvent(frame, + swingID, swingWhen, swingModifiers, swingKeyCode, + swingChar); AccessController.doPrivileged(new PostEventAction(keyEvent)); } } } +