--- old/modules/javafx.swing/src/main/java/javafx/embed/swing/SwingNode.java 2016-11-07 18:18:33.580105900 +0300 +++ new/modules/javafx.swing/src/main/java/javafx/embed/swing/SwingNode.java 2016-11-07 18:18:32.968103800 +0300 @@ -39,11 +39,7 @@ import javafx.scene.input.ScrollEvent; import javafx.stage.Window; import javax.swing.JComponent; -import java.awt.AWTEvent; -import java.awt.Component; -import java.awt.Cursor; -import java.awt.EventQueue; -import java.awt.Toolkit; +import java.awt.*; import java.awt.dnd.DragGestureEvent; import java.awt.dnd.DragGestureListener; import java.awt.dnd.DragGestureRecognizer; @@ -175,8 +171,6 @@ private boolean skipBackwardUnrgabNotification; private boolean grabbed; // lwframe initiated grab - private volatile int scale = 1; - { // To initialize the class helper at the begining each constructor of this class SwingNodeHelper.initHelper(this); @@ -191,9 +185,8 @@ setEventHandler(KeyEvent.ANY, new SwingKeyEventHandler()); setEventHandler(ScrollEvent.SCROLL, new SwingScrollEventHandler()); - focusedProperty().addListener((observable, oldValue, newValue) -> { - activateLwFrame(newValue); - }); + focusedProperty().addListener((observable, oldValue, newValue) -> + activateLwFrame(newValue)); //Workaround for RT-34170 javafx.scene.text.Font.getFamilies(); @@ -235,8 +228,9 @@ private static final class OptionalMethod<T> { private final Method method; + private final boolean isIntegerAPI; - public OptionalMethod(Class<T> cls, String name, Class<?>... args) { + OptionalMethod(Class<T> cls, String name, Class<?>... args) { Method m; try { m = cls.getMethod(name, args); @@ -247,12 +241,18 @@ throw new RuntimeException("Error when calling " + cls.getName() + ".getMethod('" + name + "').", ex); } method = m; + isIntegerAPI = args != null && args.length > 0 && + args[0] == Integer.TYPE; } public boolean isSupported() { return method != null; } + public boolean isIntegerApi() { + return isIntegerAPI; + } + public Object invoke(T object, Object... args) { if (method != null) { try { @@ -270,8 +270,16 @@ * Calls JLightweightFrame.notifyDisplayChanged. * Must be called on EDT only. */ - private static final OptionalMethod<JLightweightFrame> jlfNotifyDisplayChanged = - new OptionalMethod<>(JLightweightFrame.class, "notifyDisplayChanged", Integer.TYPE); + private static OptionalMethod<JLightweightFrame> jlfNotifyDisplayChanged; + + static { + jlfNotifyDisplayChanged = new OptionalMethod<>(JLightweightFrame.class, + "notifyDisplayChanged", Double.TYPE, Double.TYPE); + if (!jlfNotifyDisplayChanged.isSupported()) { + jlfNotifyDisplayChanged = new OptionalMethod<>( + JLightweightFrame.class,"notifyDisplayChanged", Integer.TYPE); + } + } /* * Called on EDT @@ -287,8 +295,7 @@ lwFrame.addWindowFocusListener(new WindowFocusListener() { @Override public void windowGainedFocus(WindowEvent e) { - SwingFXUtils.runOnFxThread(() -> - SwingNode.this.requestFocus()); + SwingFXUtils.runOnFxThread(SwingNode.this::requestFocus); } @Override public void windowLostFocus(WindowEvent e) { @@ -296,7 +303,16 @@ } }); - jlfNotifyDisplayChanged.invoke(lwFrame, scale); + 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()); + } + } lwFrame.setContent(new SwingNodeContent(content)); lwFrame.setVisible(true); @@ -319,10 +335,11 @@ final int x, final int y, final int w, final int h, final int linestride, - final int scale) + final double scaleX, + final double scaleY) { Runnable r = () -> peer.setImageBuffer(IntBuffer.wrap(data), x, y, w, h, - w, h, linestride, scale); + w, h, linestride, scaleX, scaleY); SwingFXUtils.runOnFxThread(() -> { if (peer != null) { r.run(); @@ -463,9 +480,7 @@ return true; } - private final InvalidationListener locationListener = observable -> { - locateLwFrame(); - }; + private final InvalidationListener locationListener = o -> locateLwFrame(); private final EventHandler<FocusUngrabEvent> ungrabHandler = event -> { if (!skipBackwardUnrgabNotification) { @@ -516,10 +531,7 @@ window.renderScaleXProperty().addListener(locationListener); window.addEventHandler(FocusUngrabEvent.FOCUS_UNGRAB, ungrabHandler); window.showingProperty().addListener(windowVisibleListener); - - // LW framework should be upgraded to separate X,Y scales... - this.scale = (int) Math.round(window.getRenderScaleX()); - setLwFrameScale(this.scale); + setLwFrameScale(window.getRenderScaleX(), window.getRenderScaleY()); } private void removeWindowListeners(final Window window) { @@ -562,9 +574,8 @@ } }); - NodeHelper.treeVisibleProperty(this).addListener((observable, oldValue, newValue) -> { - setLwFrameVisible(newValue); - }); + NodeHelper.treeVisibleProperty(this).addListener( + (observable, oldValue, newValue) -> setLwFrameVisible(newValue)); return peer; } @@ -599,10 +610,8 @@ return; } Window w = getScene().getWindow(); - float renderScaleX = (float) w.getRenderScaleX(); - int lwScale = Math.round(renderScaleX); - boolean sendScale = (this.scale != lwScale); - this.scale = lwScale; + double renderScaleX = w.getRenderScaleX(); + double renderScaleY = w.getRenderScaleY(); final Point2D loc = localToScene(0, 0); final int windowX = (int) (w.getX()); final int windowY = (int) (w.getY()); @@ -615,11 +624,14 @@ SwingFXUtils.runOnEDT(() -> { if (lwFrame != null) { - if (sendScale) { - jlfNotifyDisplayChanged.invoke(lwFrame, scale); + if (jlfNotifyDisplayChanged.isIntegerApi()) { + jlfNotifyDisplayChanged.invoke(lwFrame, + (int)Math.round(renderScaleX)); + } else { + jlfNotifyDisplayChanged.invoke(lwFrame, renderScaleX, + renderScaleY); } - lwFrame.setSize(frameW, frameH); - lwFrame.setLocation(frameX, frameY); + lwFrame.setBounds(frameX, frameY, frameW, frameH); jlfSetHostBounds.invoke(lwFrame, windowX, windowY, windowW, windowH); } @@ -660,15 +672,17 @@ }); } - private void setLwFrameScale(final int scale) { + private void setLwFrameScale(final double scaleX, final double scaleY) { if (lwFrame == null) { return; } - SwingFXUtils.runOnEDT(new Runnable() { - @Override - public void run() { - if (lwFrame != null) { - jlfNotifyDisplayChanged.invoke(lwFrame, scale); + SwingFXUtils.runOnEDT(() -> { + if (lwFrame != null) { + if (jlfNotifyDisplayChanged.isIntegerApi()) { + jlfNotifyDisplayChanged.invoke(lwFrame, + (int)Math.round(scaleX)); + } else { + jlfNotifyDisplayChanged.invoke(lwFrame, scaleX, scaleY); } } }); @@ -694,7 +708,7 @@ private JComponent comp; private volatile FXDnD dnd; - public SwingNodeContent(JComponent comp) { + SwingNodeContent(JComponent comp) { this.comp = comp; } @Override @@ -718,7 +732,11 @@ } //@Override public void imageBufferReset(int[] data, int x, int y, int width, int height, int linestride, int scale) { - SwingNode.this.setImageBuffer(data, x, y, width, height, linestride, scale); + SwingNode.this.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.this.setImageBuffer(data, x, y, width, height, linestride, scaleX, scaleY); } @Override public void imageReshaped(int x, int y, int width, int height) { @@ -839,7 +857,7 @@ private class PostEventAction implements PrivilegedAction<Void> { private AWTEvent event; - public PostEventAction(AWTEvent event) { + PostEventAction(AWTEvent event) { this.event = event; } @Override