javamacosretina-displaydpihidpi

How to find real display density (DPI) from Java code?


I'm going to do some low-level rendering stuff, but I need to know real display DPI for making everything of correct size.

I've found one way to do this: java.awt.Toolkit.getDefaultToolkit().getScreenResolution() — but it returns incorrect result on OS X with "retina" display, it's 1/2 of the real DPI. (In my case it should be 220, but it's 110)

So either some other, more correct API must be available, or alternatively I need to implement a hack just for OS X — somehow find if the current display is "retina". But I couldn't find any way to query for this information too. There's this answer but on my machine Toolkit.getDefaultToolkit().getDesktopProperty("apple.awt.contentScaleFactor") just returns null.

How can I do it?


Solution

  • Looks like it's currently possible to get it from java.awt.GraphicsEnvironment. Here's commented code example which does work on latest JDK (8u112).

    // find the display device of interest
    final GraphicsDevice defaultScreenDevice = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
    
    // on OS X, it would be CGraphicsDevice
    if (defaultScreenDevice instanceof CGraphicsDevice) {
        final CGraphicsDevice device = (CGraphicsDevice) defaultScreenDevice;
    
        // this is the missing correction factor, it's equal to 2 on HiDPI a.k.a. Retina displays
        final int scaleFactor = device.getScaleFactor();
    
        // now we can compute the real DPI of the screen
        final double realDPI = scaleFactor * (device.getXResolution() + device.getYResolution()) / 2;
    }