如何检测用户是否使用Java进行视网膜显示?我已经知道使用Toolkit.getDefaultToolkit().getDesktopProperty("apple.awt.contentScaleFactor")
检测比例因子,但java不允许我将返回的值转换为int。我想知道如何将其转换为int或其他检测视网膜显示的方法。
答案 0 :(得分:5)
我会以这种方式获得价值 -
public static boolean hasRetinaDisplay() {
Object obj = Toolkit.getDefaultToolkit()
.getDesktopProperty(
"apple.awt.contentScaleFactor");
if (obj instanceof Float) {
Float f = (Float) obj;
int scale = f.intValue();
return (scale == 2); // 1 indicates a regular mac display.
}
return false;
}
答案 1 :(得分:1)
对于Java 9,这也有效:
public static boolean isMacRetinaDisplay() {
final GraphicsConfiguration gfxConfig = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
final AffineTransform transform = gfxConfig.getDefaultTransform();
return !transform.isIdentity();
}
您也可以检查变换的比例因子,检查它是否等于2,否则回落到非视网膜。
答案 2 :(得分:0)
请注意,用户可能具有多个显示!在这种情况下,“检测视网膜显示”是什么意思?
对于大多数用途,您有兴趣将图像渲染到GUI组件上。因此,您需要检测组件处于打开状态。
幸运的是,java.awt.Component
有一个getGraphicsConfiguration
method为我们提供了必要的信息。
但是,Java 8(和7)和Java 9需要不同的处理方式:Java 9直接通过graphics device’s default transform公开必要的信息。 Java 7和8也公开了此转换,但是即使对于Retina显示器,也始终将其设置为身份转换(即无转换)。
对于Java <9,我们需要使用反射来查询为Mac实现图形的OpenJDK类中的macOS特定字段。
下面的类对Retina显示器进行必要的检查,并适用于Java 8和Java9。Java7可能也可以进行一些微小的更改,但我没有对其进行测试。
package me.klmr.ui;
import java.awt.*;
import java.lang.reflect.Method;
public final class Device {
private enum JavaVersion {
V8,
V9
}
private static final JavaVersion JAVA_VERSION = getJavaVersion();
private static JavaVersion getJavaVersion() {
final String versionString = System.getProperty("java.version");
if (versionString.startsWith("1.8")) return JavaVersion.V8;
if (versionString.startsWith("9.")) return JavaVersion.V9;
throw new RuntimeException("Unsupported Java version");
}
public static GraphicsConfiguration getCurrentConfiguration(final Component component) {
final GraphicsConfiguration graphicsConfiguration = component.getGraphicsConfiguration();
if (graphicsConfiguration == null) {
return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
} else {
return graphicsConfiguration;
}
}
public static GraphicsDevice getCurrentDevice(final Component component) {
final GraphicsConfiguration graphicsConfiguration = component.getGraphicsConfiguration();
if (graphicsConfiguration == null) {
return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
} else {
return graphicsConfiguration.getDevice();
}
}
public static boolean isOnRetinaDisplay(final Component component) {
switch (JAVA_VERSION) {
case V8: return isOnRetinaDisplayJava8(component);
case V9: return isOnRetinaDisplayJava9(component);
default: throw new AssertionError("Unreachable");
}
}
public static double getDisplayScalingFactor(final Component component) {
switch (JAVA_VERSION) {
case V8: return getDisplayScalingFactorJava8(component);
case V9: return getDisplayScalingFactorJava9(component);
default: throw new AssertionError("Unreachable");
}
}
private static boolean isOnRetinaDisplayJava8(final Component component) {
final GraphicsDevice device = getCurrentDevice(component);
try {
final Method getScaleFactorMethod = device.getClass().getMethod("getScaleFactor");
final Object scale = getScaleFactorMethod.invoke(device);
return scale instanceof Integer && ((Integer) scale).intValue() == 2;
} catch (ReflectiveOperationException e) {
return false;
}
}
private static boolean isOnRetinaDisplayJava9(final Component component) {
return ! getCurrentConfiguration(component).getDefaultTransform().isIdentity();
}
private static double getDisplayScalingFactorJava8(final Component component) {
return isOnRetinaDisplayJava8(component) ? 2.0 : 1.0;
}
private static double getDisplayScalingFactorJava9(final Component component) {
return getCurrentConfiguration(component).getDefaultTransform().getScaleX();
}
}
实际上,将对话框从一个屏幕移动到另一个屏幕将导致组件重新呈现。如果组件的渲染代码使用上述类来找出正确的分辨率,则无论它们当前在哪个显示上,它们都将正确渲染。