如何在Java中检测视网膜显示?
如何在Java中检测用户是否有视网膜显示器?我已经知道使用如何在Java中检测视网膜显示?,java,retina-display,Java,Retina Display,如何在Java中检测用户是否有视网膜显示器?我已经知道使用Toolkit.getDefaultToolkit().getDesktopProperty(“apple.awt.contentScaleFactor”)检测比例因子,但是java不允许我将返回值转换为int。我想知道如何将其转换为int,或者用另一种方法检测视网膜显示。我会这样得到值- public static boolean hasRetinaDisplay() { Object obj = Toolkit.getDefaul
Toolkit.getDefaultToolkit().getDesktopProperty(“apple.awt.contentScaleFactor”)
检测比例因子,但是java不允许我将返回值转换为int。我想知道如何将其转换为int,或者用另一种方法检测视网膜显示。我会这样得到值-
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;
}
对于Java 9,这同样有效:
public static boolean isMacRetinaDisplay() {
final GraphicsConfiguration gfxConfig = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
final AffineTransform transform = gfxConfig.getDefaultTransform();
return !transform.isIdentity();
}
您也可以检查变换的比例因子,检查它是否等于2,否则返回到非视网膜。注意,用户可能有多个显示器在这种情况下,“检测视网膜显示”是什么意思 对于大多数目的,您感兴趣的是将图像呈现到GUI组件上。因此,您需要检测组件的显示内容 幸运的是,
java.awt.Component
有一个为我们提供必要信息的
但是,Java8(和Java7)和Java9需要不同的处理:Java9直接通过。Java7和Java8也公开了这种转换,但它总是设置为身份转换(即不转换),即使对于视网膜显示也是如此
对于Java<9,我们需要使用反射来查询实现Mac图形的OpenJDK类中特定于macOS的字段
下面的类实现了视网膜显示的必要检查,适用于Java8和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();
}
}
实际上,将对话框从一个屏幕移动到另一个屏幕将导致组件重新渲染。如果组件的渲染代码使用上述类来确定正确的分辨率,则无论当前在哪个显示器上,它们都将正确渲染。如何在带有视网膜显示器的设备上运行Java?或者我的意思是,你在运行哪个Java…你在使用什么不允许你将返回值转换成int?(它应该是一个浮点数)。我正在MacBookPro上运行它,带有视网膜显示器。当我运行代码并尝试将返回值类型转换为
整数
时,会出现一个错误,即线程“main”java.lang.ClassCastException中的异常:java.lang.Float不能转换为java.lang.Integer
,不要这样做!只需使用…Java不会让我这么做,因为“类型对象的方法intValue()未定义。”非常感谢,这很有效。我想我只需要if语句,并在将其转换为int之前将其转换为float。请问视网膜显示的值是多少?我将改写一个完全实用的方法的答案…如果它是视网膜显示器,你会得到2个,如果它不是,并且计算机是mac,则得到1个,否则为空。最好有一些能与Oracle JDK一起工作的东西,因为新的JDK现在支持视网膜显示器。在最新的Oracle JDK上不适用,obj
只是为空,然而,我找到了获取这些信息的另一种方法,并编写了这个Java9的具体特性是什么?在Java 7中编译(尚未运行它,不要使用愚蠢的Retina Mac)。@NateS API存在,但在Java 9之前它返回错误的值:Java 7和Java 8甚至在Retina显示器上使用标识转换,ScaleX
和ScaleY
值始终为1.0,而不管实际的硬件显示比例值如何。