1

我要做一些低级渲染的东西,但我需要知道真实的显示 DPI 才能使所有东西都具有正确的大小。

我找到了一种方法来做到这一点: java.awt.Toolkit.getDefaultToolkit().getScreenResolution()- 但它在带有“retina”显示的 OS X 上返回不正确的结果,它是真实 DPI 的 1/2。(在我的情况下应该是 220,但它是 110)

因此,要么必须提供其他一些更正确的 API,要么我需要为 OS X 实现一个 hack——以某种方式找到当前显示是否是“视网膜”。但我也找不到任何方法来查询这些信息。有这个答案,但在我的机器上Toolkit.getDefaultToolkit().getDesktopProperty("apple.awt.contentScaleFactor")只返回空值。

我该怎么做?

4

2 回答 2

3

看起来目前可以从java.awt.GraphicsEnvironment. 这是在最新的 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;
}
于 2016-11-03T11:05:08.873 回答
2

这是一个来自@sarge-borsch 的示例,它不会在 Windows 和 Linux 上引发编译错误。

public static int getScaleFactor() {
    try {
        // Use reflection to avoid compile errors on non-macOS environments
        Object screen = Class.forName("sun.awt.CGraphicsDevice").cast(GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice());
        Method getScaleFactor = screen.getClass().getDeclaredMethod("getScaleFactor");
        Object obj = getScaleFactor.invoke(screen);
        if (obj instanceof Integer) {
            return ((Integer)obj).intValue();
        }
    } catch (Exception e) {
        System.out.println("Unable to determine screen scale factor.  Defaulting to 1.");
    }
    return 1;
}
于 2018-11-14T05:46:18.863 回答