仅使用公共API在JavaFX中获取屏幕比例

仅使用公共API在JavaFX中获取屏幕比例,java,svg,javafx-8,Java,Svg,Javafx 8,我正在尝试制作一个JavaFX库,该库将SVG文件显示为图像,可用于所有Java 8版本: 问题是它使用java.fx.Screen的renderScale属性,该属性是私有的,在公共API中似乎没有直接或间接的访问器 在大多数情况下,该值为1.0f,对于Mac上的视网膜显示,该值可能为2.0f com.sun.javafx.tk.quantum.QuantumToolkit.getMaxRenderScale(); 这给出了我想要的值,但是在com.sun包中,所以不在公共API中,并且可以

我正在尝试制作一个JavaFX库,该库将SVG文件显示为图像,可用于所有Java 8版本:

问题是它使用java.fx.Screen的renderScale属性,该属性是私有的,在公共API中似乎没有直接或间接的访问器

在大多数情况下,该值为1.0f,对于Mac上的视网膜显示,该值可能为2.0f

com.sun.javafx.tk.quantum.QuantumToolkit.getMaxRenderScale();
这给出了我想要的值,但是在com.sun包中,所以不在公共API中,并且可以在次要版本之间更改(并且确实更改,请参见下面的重命名)

com.sun.glass.ui.Screen.getRenderScale();
不在公共API中,在以前的版本中命名为getScale()

对以下访问器进行相同的重命名,其目的是公开内部属性

com.sun.javafx.stage.ScreenHelper.getScreenAccessor(Screen).getRenderScale();
// was ScreenHelper.getScreenAccessor(Screen).getScale()  in previous version
如果我使用这些内部API,它可以用于最后一个版本:1.8.0_74,但对于某些以前的版本(例如1.8.0_51),它会给出NoSuchMethodError

我如何使它适用于所有Java8版本的jre


请注意,我尝试了从dpi计算它的简单方法,但我应该只得到四舍五入值(1.0或2.0),并且我没有缩放计算的规则。

我为自己编写了一个类似这样的辅助方法

public static double getRenderScale(Screen screen) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    Method m;
    try {
        m = Screen.class.getDeclaredMethod("getScale"); // until 8u60 b15
    } catch (NoSuchMethodException e) {
        m = Screen.class.getDeclaredMethod("getRenderScale");
    }
    m.setAccessible(true);
    return ((Float) m.invoke(screen)).doubleValue();
}

这是一种暴力手段,但我还没有找到更好的办法。

你用这种手段干什么?系统不能猜测初始值并让用户进行配置吗?好吧,这是一个很好的问题:简单的回答是我分叉了这个库,只想在不进行任何结构更改的情况下执行一个pull请求。很长的答案是,我在没有配置的情况下包含了FX组件“Image”,因为它是一个内部JavaFX组件,我不想包装它,让比例自行计算以实现高密度显示。但也有一个隐藏的问题:如何处理javaFX内部API,以及Java SE兼容性中断?隐藏问题的明显答案是:不要使用内部API或在以后遭受其攻击:-)我的个人首选是后者,这并不总是可能的,though@kleopatra你是对的,这就是为什么我不喜欢我的3个解决方案中的任何一个。问题是我不知道如何用这个API提供我们自己的组件,因为例如quantum层不是公共API:h的一部分ttp://docs.oracle.com/javafx/2/architecture/jfxpub-architecture.htmyou 可以考虑发布到FX DEV邮件列表-API可以改变(在游戏中有点迟了9),这是什么想法,但它仍然使用内部API,只是用反射隐藏它,如果将来再次重命名它,它将失败。如果不存在任何方法,我们可以添加另一个带有回退的捕获。无论如何添加+1,因为它回答了“如何处理JavaSE兼容性中断”。