如何在高 DPI 显示器上运行放大的 Java 应用程序?

Jef*_*eff 100 java high-dpi windows-10

我正在尝试在 Windows 10 的高 DPI 显示器上运行 Java 应用程序(JAR 文件)。该应用程序使用 Swing,因此不支持 DPI。通常,当我运行一个不支持 DPI 的应用程序时,Windows 会为我缩放它,尽管它很模糊。但出于某种原因,它没有扩展 Java 应用程序;我只是在角落里有一个小窗口,上面有无法阅读的文字。如何使用 Windows 的高 DPI(模糊)缩放运行 Java 应用程序?

Eld*_*rry 100

刚刚在我的 Windows 10 机器上找到了一个简单的解决方案:

  1. 找到java.exe你安装了。
  2. 右键单击-> Properties
  3. 转到Compatibility选项卡
  4. 查看 Override high DPI scaling behavior.
  5. 选择SystemScaling performed by:

  • 我使用了一个侵入性较小的变体。我为命令 `java -jar myJarFile.jar` 创建了一个快捷方式,并在该快捷方式(Windows 10、Java 8)上执行了步骤 2 到 5。 (6认同)
  • 最佳解决方案 - 我在运行 .jnlp 文件时遇到了这个问题,所以我不得不更改“C:\Program Files\Java\jre1.8.0_131\bin\jp2launcher.exe”,但这就像魅力一样。 (5认同)
  • 对我来说,它是`javaw.exe` (4认同)
  • 对于运行基于 Java 的 Minecraft 启动器的 Windows 10,我必须更改系统上所有已安装的 Java 版本才能使其工作(java.exe 和 javaw.exe)。 (3认同)

Car*_*rlG 43

这里的问题似乎是 Swing 在默认情况下声称它是 DPI 感知的,因此 Windows 不会对其进行缩放。使用此开关关闭此行为,Windows 将开始缩放您的 Swing 应用程序:

-Dsun.java2d.dpiaware=false
Run Code Online (Sandbox Code Playgroud)

[编辑:不幸的是,这个标志似乎不再适用于 Java 8,我正在 Java 6 中测试它。看起来这是一个已知问题。]

[编辑 2:您可以修改 Java 8 安装以使其正常工作,使用程序修改 EXE 清单。我在 java.exe 和 javaw.exe 内的清单中将设置从 true 更改为 false,现在我的 Swing 程序可以在 Windows 10 高 dpi 中正确缩放。我为此使用了资源调谐器。]

[编辑 3] 只使用 Java 9

  • 这介于可笑和滑稽之间。框架错误地报告了它的能力,并删除了修复错误的开关。唯一的解决办法?供最终用户购买第 3 方工具。人们想知道为什么 Java 的名声如此糟糕。 (4认同)

Chr*_*jer 32

如果您偶然发现了这个问题,但实际上正在寻找适用于 Linux 的解决方案,那么这适合您。

如果您可以向java启动应用程序的二进制文件添加参数,您可以使用该选项-Dsun.java2d.uiScale属性传递一个值,以指定 Java2D 的缩放因子。这将扩展您的应用程序。缩放因子值是双精度值。确保将此选项传递给java二进制文件本身,而不是已启动的 Java 应用程序。

示例:以 2.5 的 UI 缩放系数启动 NearInfinity.jar

java -Dsun.java2d.uiScale=2.5 -jar ~/jars/NearInfinity.jar
Run Code Online (Sandbox Code Playgroud)

或者,您可以设置GDK_SCALE环境变量。例子:

GDK_SCALE=2 java -jar ~/jars/NearInfinity.jar
Run Code Online (Sandbox Code Playgroud)

我发现这篇 ArchLinux Wiki 文章对于在 HiDPI 系统上运行 Linux 非常有用,并且其中一些内容也可能适用于 Windows。


小智 14

解决方案:在 JRE 9 上运行它。

这是因为 Java 运行时声明自己是“DPI 感知的”,但并不真正支持 AWT 和 Swing。Java 应用程序的大小和渲染基于像素而不是适当的缩放,这包括 HiDPI 显示器。无论如何,这最近已经解决了。请参阅问题JEP 263:Windows 和 Linux 上的 HiDPI 图形 以及升级

因此,增加字体大小不起作用(因为它不会增加其余的东西);jvm 参数-Dsun.java2d.dpiaware=false不起作用(因为它不被真正支持);并且清单文件 + 注册表编辑(适用于 Windows)不起作用。

然后,您需要在 JRE 9 上运行它,因为它确实支持此功能。

  • @Ramhound 您不必重新编译。我刚刚用 JDK8 为 Java 8 构建了一个 jar,它在具有 4K 屏幕和 200% 比例设置的 W10 系统上覆盖了全屏 JPanel 的 paint() 方法。用Java 8的java.exe运行,给方法的Graphics2D对象缩放为1,JPanel的getWidth/height为3840x2160。用Java 9的java.exe运行,缩放为2,宽/高为1920x1080。 (4认同)
  • 这未能指出您必须重新编译代码。简单地在 Java 9+ 上运行相同的 Java 8- 应用程序不会改变行为 (3认同)
  • @wax_lyrical 无需猜测;必要的 API 实际上已经存在很长时间了。获取“GraphicsConfiguration”,可以使用“GraphicsEnvironment.getLocalGraphicsEnvironment() .getDefaultScreenDevice() .getDefaultConfiguration()”来获取默认值,也可以仅在实际可见的 AWT“Component”上使用“.getGraphicsConfiguration()”。然后,您可以调用 .getDefaultTransform() 来获取其缩放组件反映设置的转换。如果您需要处理“BufferedImage”等,需要像素,请将变换应用于尺寸,然后使用标识来绘制到屏幕。 (2认同)

mas*_*ilo 6

要强制所有 java 可执行文件将“属性 > 兼容性 > dpi 缩放模式”设置为“系统”,请在管理员 powershell (win-x, a) 中运行:

$javaexes = (Get-ChildItem -path "$env:ProgramFiles\Java","${env:ProgramFiles(x86)}\java" -filter java?.exe -recurse  | Where-Object {$_.Name -match "java(|w).exe"} ).fullname

$javaexes | foreach {REG ADD "HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers"  /V $_ /T REG_SZ /D "~ DPIUNAWARE" /F}
Run Code Online (Sandbox Code Playgroud)

撤销:

$javaexes | foreach {REG delete "HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers"  /V $_ /f}
Run Code Online (Sandbox Code Playgroud)

您可以使用 HKLM 代替 HKCU,但是您无法再在 java*.exe 文件的属性 > 兼容性对话框中手动更改 dpi 缩放设置。