使用4K监视器的Java中的错误SWING组件放置

时间:2016-02-02 15:41:04

标签: java swing high-resolution

我有元件放置问题。首先,我将尝试提供(可能有用的)信息,然后告诉您主要问题:

我的系统:Windows 8.1 64位,Java 1.8.0_60 32位

我要做的是:在我学习所有连接屏幕的屏幕分辨率后,我在屏幕周围放置了一些摆动组件。这意味着我需要知道屏幕的分辨率。

我正在使用多台显示器。

  1. 3840 x 2160(主监视器)
  2. 1920 x 1080(二级)
  3. 我用:

    graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();
    devices = graphicsEnvironment.getScreenDevices();
    

    对于主屏幕设备:

    devices[i].getDefaultConfiguration().getBounds()
    

    返回[0,0,2560,1440]。而不是正确的值3840 x 2160。

    有趣的是;

    devices[i].getDisplayMode().getWidth() and getHeight() 
    

    返回正确的3840和2160值。

    注意:在屏幕的任何其他分辨率选择中不会发生这种差异。例如,如果我为主屏幕选择1920 x 1080,则“getDefaultConfiguration()。getBounds()”和“getDisplayMode()。getWidth()”将返回正确的值。

    现在,

    你可以说我已经获得了正确的尺寸。那么,怎么回事?

    问题是,当我尝试定位我的SWING组件时,它们被放置在错误的位置。例如,[3750,0,10,10]处的元素在第二个监视器内部结束,而它应该位于第一个屏幕的右上角。

    另一个例子:如您所知,固定大小的组件在较高分辨率下会显得较小。由于与屏幕相关的像素百分比变小,因此组件本身也看起来更小。例如;当我将屏幕的分辨率从1920x1080增加到2560x1440时,我的组件会变小。但是,当我将分辨率从2560x1440提高到3840x2160时;他们保持相同的规模。

    我希望我对这个问题很清楚。

    由于

1 个答案:

答案 0 :(得分:2)

我知道一个Windows 8+特定功能,可能以这种方式表现出来:per-display DPI setting。该功能应该使应用程序窗口在物理上保持相同的大小,即使将它们拖动到具有不同密度的显示器上也是如此。

这是通过将应用程序的窗口渲染到中间缓冲区来实现的,然后由DWM缩放,将目标屏幕DPI考虑在内。

可以使用以下对话框禁用此功能:

Compatibility settings

必须在包含可执行程序的文件上完成,该程序显示任何帧。在Java中,它有点令人费解,因为它是一个托管应用程序。在java(w).exe上更改此值应该全局改变行为。

通常,这种标志调整由软件安装程序完成。可以使用瘦包装将java jar包装到exe中。我最喜欢launch4j这项任务。包装器exe和jar文件可以包装到安装程序脚本中,该脚本在安装时设置标志。