question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Canvas embedded in Swing application renders at wrong scale on HiDPI

See original GitHub issue

I am trying to embed JMonkeyEngine into a Swing application and noticed the Canvas is rendering at a different scale on HiDPI displays, the screenshot below is on a 200% scale display. I set a custom background color on the canvas to make sure it has the correct dimensions.

jme3tests

I combined the TetsGltfLoading class with some sample code for embedding the canvas:

package nl.rp.ddd.jme;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

import com.jme3.system.AppSettings;
import com.jme3.system.JmeCanvasContext;

public class JmeTests {


	public JmeTests() {

		final JFrame frame = new JFrame();
		frame.setTitle("JME 3 Tests");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(800, 600);

		AppSettings settings = new AppSettings(true);
		settings.setWidth(800);
		settings.setHeight(600);
		settings.setVSync(true);

		TestGltfLoading canvasApplication = new TestGltfLoading();
		canvasApplication.setSettings(settings);
		canvasApplication.setDisplayStatView(false);
		canvasApplication.setDisplayFps(false);
		canvasApplication.createCanvas();
		JmeCanvasContext ctx = (JmeCanvasContext) canvasApplication.getContext();
		ctx.setSystemListener(canvasApplication);
		Dimension dim = new Dimension(800, 600);
		ctx.getCanvas().setPreferredSize(dim);
		ctx.getCanvas().setBackground(new Color(50, 50, 100));

		frame.getContentPane().setLayout(new BorderLayout());
		frame.getContentPane().add(ctx.getCanvas(), BorderLayout.CENTER);

		frame.pack();
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);

	}

	public static void main(String[] args) {
		System.setProperty("org.lwjgl.opengl.Display.enableHighDPI", "true");
		SwingUtilities.invokeLater(new Runnable() {

			@Override
			public void run() {
				new JmeTests();
			}
		});
	}

}

I tested this with 3.3.2-stable, jme3-lwjgl (embedding a canvas failed with jme3-lwjgl3), java 10 and java 11 runtimes.

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
remcopoelstracommented, Mar 30, 2021

I managed to work around it for now by resizing the canvas myself (zooming in on the scene in the upper left corner), for this I override doLayout() of the parent container:

@Override
public void doLayout() {
	if (canvas != null && scale != null) {
		canvas.setBounds(0, 0, (int)(getWidth() * scale), (int)(getHeight() * scale));
	} else {
		super.doLayout();
	}
}

This does have some issues though, overlay text is rendered at wrong scale for example. I wouldn’t consider this workaround a solution to the problem.

I also did some experimenting with embedding a canvas with lwjgl3 (because I would prefer to use this instead of lwjgl2). I was able to embed a canvas on Windows with glfwAttachWin32Window() but I still have to try to get keyboard/mouse input working correctly. See this issue for more info on attaching glfw to an existing handle: https://github.com/glfw/glfw/issues/25

0reactions
glowluxcommented, Oct 15, 2022

This seems related… solution looks good. https://forum.jogamp.org/GLcanvas-vs-NEWT-on-Hi-DPI-Screens-tp4041191p4041642.html

I think returning scaled sizes from the getHeight() and getWidth() methods of the canvas is better and seems to break less things. Modified LwjglCanvas.java

Not submitting this as change though, because I’m unsure if this workaround breaks anything else…

Read more comments on GitHub >

github_iconTop Results From Across the Web

Canvas in webview displayed with wrong scale on Windows
Can be reproduced in latest openjfx14 but can't be reproduced in java 8. ... Issue: HiDPI problem. WebView rendering uses ceil(1.5x) = 2x...
Read more >
Canvas in webview displayed with wrong scale on Windows
Issue: HiDPI problem. WebView rendering uses ceil(1.5x) = 2x while canvas and svg rendering uses 1.5x as pixel scale. Fix: Use the ceil()...
Read more >
1358 – Incorrect OpenGL surface size on SWT GLCanvas and ...
When using high DPI displays, it is usually required to scale up UI and Text to keep things readable. Eclipse and SWT work...
Read more >
Resolve DPI-scaling when embedding JavaFX within SWT ...
This is a known problem: https://bugs.openjdk.java.net/browse/JDK-8191661. The fix is not likely until a couple of releases later.
Read more >
A few HiDPI tricks for Linux - Hacker News
In the display settings you can pick a scale per monitor and almost all apps will respect it. (It seems some apps with...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found