Skip to content

Commit f4e27e9

Browse files
author
Johan Vos
committedNov 10, 2022
8222210: JFXPanel popups open at wrong coordinates when using multiple hidpi monitors
Reviewed-by: kcr, angorya
1 parent 706261b commit f4e27e9

File tree

2 files changed

+54
-5
lines changed

2 files changed

+54
-5
lines changed
 

‎modules/javafx.graphics/src/main/java/module-info.java

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868

6969
exports com.sun.glass.ui to
7070
javafx.media,
71+
javafx.swing,
7172
javafx.web;
7273
exports com.sun.glass.utils to
7374
javafx.media,

‎modules/javafx.swing/src/main/java/javafx/embed/swing/JFXPanel.java

+53-5
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
import java.awt.EventQueue;
3939
import java.awt.SecondaryLoop;
4040
import java.awt.GraphicsEnvironment;
41+
import java.awt.GraphicsConfiguration;
42+
import java.awt.Rectangle;
4143
import java.awt.event.AWTEventListener;
4244
import java.awt.event.ComponentEvent;
4345
import java.awt.event.FocusEvent;
@@ -48,6 +50,7 @@
4850
import java.awt.event.MouseEvent;
4951
import java.awt.event.MouseWheelEvent;
5052
import java.awt.event.InvocationEvent;
53+
import java.awt.geom.AffineTransform;
5154
import java.awt.im.InputMethodRequests;
5255
import java.awt.image.BufferedImage;
5356
import java.awt.image.DataBufferInt;
@@ -59,7 +62,9 @@
5962
import javax.swing.SwingUtilities;
6063

6164
import javafx.application.Platform;
65+
import javafx.geometry.Point2D;
6266
import javafx.scene.Scene;
67+
import com.sun.glass.ui.Screen;
6368

6469
import com.sun.javafx.application.PlatformImpl;
6570
import com.sun.javafx.cursor.CursorFrame;
@@ -362,6 +367,44 @@ public final boolean isOpaque() {
362367
return false;
363368
}
364369

370+
// we need to know the JavaFX screen of the current AWT graphcisConfiguration
371+
private Screen findScreen(GraphicsConfiguration graphicsConfiguration) {
372+
Rectangle awtBounds = graphicsConfiguration.getBounds();
373+
AffineTransform awtScales = graphicsConfiguration.getDefaultTransform();
374+
for (Screen screen : Screen.getScreens()) {
375+
if ((Math.abs(screen.getPlatformX() - awtBounds.getX()) < 2.) &&
376+
(Math.abs(screen.getPlatformY() - awtBounds.getY()) < 2.) &&
377+
(Math.abs(screen.getPlatformWidth() - awtScales.getScaleX() * awtBounds.getWidth()) < 2.) &&
378+
(Math.abs(screen.getPlatformHeight() - awtScales.getScaleY() * awtBounds.getHeight()) < 2.)) {
379+
return screen;
380+
}
381+
}
382+
return null;
383+
}
384+
385+
private Point2D convertSwingToFxPixel(GraphicsConfiguration g, double wx, double wy) {
386+
double newx, newy;
387+
Screen screen = findScreen(g);
388+
if (screen != null) {
389+
AffineTransform awtScales = getGraphicsConfiguration().getDefaultTransform();
390+
float pScaleX = screen.getPlatformScaleX();
391+
float pScaleY = screen.getPlatformScaleY();
392+
int sx = screen.getX();
393+
int sy = screen.getY();
394+
double awtScaleX = awtScales.getScaleX();
395+
double awtScaleY = awtScales.getScaleY();
396+
397+
int px = screen.getPlatformX();
398+
int py = screen.getPlatformY();
399+
newx = sx + (wx - px) * awtScaleX / pScaleX;
400+
newy = sy + (wy - py) * awtScaleY / pScaleY;
401+
} else {
402+
newx = wx;
403+
newy = wy;
404+
}
405+
return new Point2D(newx, newy);
406+
}
407+
365408
private void sendMouseEventToFX(MouseEvent e) {
366409
if (scenePeer == null || !isFxEnabled()) {
367410
return;
@@ -407,14 +450,17 @@ private void sendMouseEventToFX(MouseEvent e) {
407450
if (e.getID() == MouseEvent.MOUSE_PRESSED || e.getID() == MouseEvent.MOUSE_RELEASED) {
408451
popupTrigger = e.isPopupTrigger();
409452
}
453+
Point2D onScreen = convertSwingToFxPixel(getGraphicsConfiguration(), e.getXOnScreen(), e.getYOnScreen());
454+
int fxXOnScreen = (int)Math.round(onScreen.getX());
455+
int fxYOnScreen = (int)Math.round(onScreen.getY());
410456

411457
if(e.getID() == MouseEvent.MOUSE_WHEEL) {
412458
scenePeer.scrollEvent(AbstractEvents.MOUSEEVENT_VERTICAL_WHEEL,
413459
0, -SwingEvents.getWheelRotation(e),
414460
0, 0, // total scroll
415461
40, 40, // multiplier
416462
e.getX(), e.getY(),
417-
e.getXOnScreen(), e.getYOnScreen(),
463+
fxXOnScreen, fxYOnScreen,
418464
(extModifiers & MouseEvent.SHIFT_DOWN_MASK) != 0,
419465
(extModifiers & MouseEvent.CTRL_DOWN_MASK) != 0,
420466
(extModifiers & MouseEvent.ALT_DOWN_MASK) != 0,
@@ -425,15 +471,16 @@ private void sendMouseEventToFX(MouseEvent e) {
425471
SwingEvents.mouseButtonToEmbedMouseButton(e.getButton(), extModifiers),
426472
primaryBtnDown, middleBtnDown, secondaryBtnDown,
427473
backBtnDown, forwardBtnDown,
428-
e.getX(), e.getY(), e.getXOnScreen(), e.getYOnScreen(),
474+
e.getX(), e.getY(),
475+
fxXOnScreen, fxYOnScreen,
429476
(extModifiers & MouseEvent.SHIFT_DOWN_MASK) != 0,
430477
(extModifiers & MouseEvent.CTRL_DOWN_MASK) != 0,
431478
(extModifiers & MouseEvent.ALT_DOWN_MASK) != 0,
432479
(extModifiers & MouseEvent.META_DOWN_MASK) != 0,
433480
popupTrigger);
434481
}
435482
if (e.isPopupTrigger()) {
436-
scenePeer.menuEvent(e.getX(), e.getY(), e.getXOnScreen(), e.getYOnScreen(), false);
483+
scenePeer.menuEvent(e.getX(), e.getY(), fxXOnScreen, fxYOnScreen, false);
437484
}
438485
}
439486

@@ -598,8 +645,9 @@ private boolean updateScreenLocation() {
598645
synchronized (getTreeLock()) {
599646
if (isShowing()) {
600647
Point p = getLocationOnScreen();
601-
screenX = p.x;
602-
screenY = p.y;
648+
Point2D fxcoord = convertSwingToFxPixel(getGraphicsConfiguration(), p.x, p.y);
649+
screenX = (int)Math.round(fxcoord.getX());
650+
screenY = (int)Math.round(fxcoord.getY());
603651
return true;
604652
}
605653
}

0 commit comments

Comments
 (0)
Please sign in to comment.