Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java中检测视网膜显示?_Java_Retina Display - Fatal编程技术网

如何在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

如何在Java中检测用户是否有视网膜显示器?我已经知道使用
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,而不管实际的硬件显示比例值如何。