如何在 Windows/Linux 上设置 Java Swing 应用程序的 DPI?

Posted

技术标签:

【中文标题】如何在 Windows/Linux 上设置 Java Swing 应用程序的 DPI?【英文标题】:How to set the DPI of Java Swing apps on Windows/Linux? 【发布时间】:2013-03-17 13:05:32 【问题描述】:

如果您有一台 DPI 超过 150 的显示器(例如 Macbook Pro),您也可能会发现问题:Java Swing 应用程序上的字体对于高 DPI 显示器来说太小了,我根本无法更改字体大小(它直接忽略 Windows DPI,只显示 非常原始的 DPI-->96)。我只能改变屏幕分辨率,这绝对会使 LCD 上的一切变得模糊。

是的,我有一台带高 DPI 显示器的笔记本电脑,15.6 英寸,分辨率为 1920x1080,一些 Java 桌面应用程序在我的笔记本电脑上看起来非常小,例如 Matlab、Burpsuite 等。我在互联网上搜索了很长时间时间,但仍然找不到解决问题的方法。我知道我可以通过JRE_HOME/lib/font/fontconfig.properties.src 更改 JRE 字体,但是我找不到任何地方可以为 Java 桌面字体设置默认字体大小或 DPI。

问题没有解决方案吗?你有高 DPI 显示器吗?你如何处理这些应用程序? Swing 会放弃高 DPI 用户吗?

【问题讨论】:

This 可能会帮助你 还有tell us your results,所以我们知道有多嫉妒。 :-) 题外话:如果普通的 Windows 程序不能很好地缩放,即使您在兼容性选项中明确了“无 DPI 缩放”标志,您可能运行的是 64 位版本的程序。请改用 32 位版本。 【参考方案1】:

我目前正在 Windows 上调查此问题。这是我发现的:

大多数 Swing 外观和感觉根本不支持高 DPI,即使 Nimbus 也不支持,即使它应该是可扩展的。我发现一些旧博客文章说 Nimbus 最终可能会提供高 DPI 缩放,但显然这从未发生过。

一个例外是系统 LAF,但在所有 DPI 设置下,其默认字体比实际系统字体大小小约 10%。此外,必须明确选择系统,如下所述: http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html

您也无法在 Swing 中设置单一的缩放因子。特定的 LAF 必须提供代码来处理缩放。所以你能做的最好的就是选择系统并希望它足够好。

但是,JavaFX 在我的系统上可以正确地自动扩展至 150%。如果可能的话,我建议您使用 JavaFX 来构建您的 GUI。

编辑:我做了几个小测试程序,并为各种 GUI 框架、Swing 主题和 DPI 设置截取了比较截图。这可能对阅读此问题的人有用:http://kynosarges.org/GuiDpiScaling.html

【讨论】:

【参考方案2】:

简短回答:您需要在 JRE 9+ 上运行它。

长答案: 这是因为 Java 运行时声明自己是“DPI-aware”的,但对于 AWT 和 Swing 并不真正支持它。 Java 应用程序的大小和渲染基于像素而不是适当缩放,这包括 HiDPI 显示。 无论如何,最近已经解决了这个问题。 查看问题JEP 263: HiDPI Graphics on Windows and Linux 和upgrade。

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

解决方案:您需要在 JRE 9+ 上运行它,因为它确实支持此功能。

【讨论】:

在 Java8 中,我通过在清单文件 javaw.exe 中切换 dpiAware 参数得到了帮助 嗨 @MisterParser,我在哪里可以找到 javaw.exe 的清单文件【参考方案3】:

answer 解决了我的 4K 屏幕 Ubuntu 笔记本电脑上的问题。

在应用程序的配置文件中,我添加了-Dsun.java2d.uiScale=2.5 Java 参数,现在,在执行时,应用程序可以很好地缩放并且可以使用。

【讨论】:

【参考方案4】:

在 Linux 上,根据我的实验,似乎不可能使用任何 Swing 外观进行缩放。但是,可以使用涉及 VNC 的 hack 来做到这一点,vncdesk。这是我在vncdesk下运行gradle --gui的配置:

.vncdesk/1/settings.ini:

[desktop]
width = 1050
height = 650

[window]
title = gradle
name = gradle in vncdesk
class = GradleInVncdesk
scale_factor = 2

.vncdesk/1/startup:

#!/bin/sh
cd "$INVOCATION_DIR"
matchbox-window-manager&
exec gradle --gui "$@"

【讨论】:

最小的matchbox-window-manager 在这种情况下是完美的。【参考方案5】:

我设法按照以下说明解决了这个问题:Link。

它是德语的,但我会翻译重要的东西。

创建此注册表项:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\SideBySide]
"PreferExternalManifest"=dword:00000001

使用此内容创建清单文件:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">

<dependency>
  <dependentAssembly>
    <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*">
    </assemblyIdentity>
  </dependentAssembly>
</dependency>

<dependency>
  <dependentAssembly>
    <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.21022.8" processorArchitecture="amd64" publicKeyToken="1fc8b3b9a1e18e3b">
    </assemblyIdentity>
  </dependentAssembly>
</dependency>

<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
  <security>
    <requestedPrivileges>
      <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
    </requestedPrivileges>
  </security>
</trustInfo>

<asmv3:application>
  <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
    <ms_windowsSettings:dpiAware xmlns:ms_windowsSettings="http://schemas.microsoft.com/SMI/2005/WindowsSettings">false</ms_windowsSettings:dpiAware>
  </asmv3:windowsSettings>
</asmv3:application>

</assembly>

将它复制到java.exe和javaw.exe所在的bin目录中,并将其命名为java.exe.manifestjavaw.exe.manifest(您将拥有两个内容相同但名称不同的文件)。

HTH。

伯纳德

【讨论】:

遗憾的是,这对我来说似乎没有任何改变。我正在运行 32 位 java,并不是说我知道我有选择,如果这会有所不同。编辑:事实上,至少在我的情况下,可以通过为有问题的单个应用程序而不是 java/javaw.exe 创建清单来解决问题。每javahacker.com/eclipse-on-a-high-dpi-display-in-windows @AlexWhittemore 阅读了链接的文章后,我不得不说,这正是它所建议的 - 创建 &lt;Application&gt;.exe.manifest 文件以禁用 DPI 缩放。与法拉利所说的不同。 @user8 我从来没有跟进过,但是是的,链接确实这么说,很好 ;) 这个方案好像只适用于Windows? 不配置注册表项,有没有办法解决这个问题?【参考方案6】:

似乎在 Linux (Gtk) 上,您可以通过在启动应用程序之前使用以下方法缩放应用程序 DPI 来解决此问题。

export GDK_SCALE=2

(您也可以降低显示器分辨率,但这根本不是解决方案)。

【讨论】:

当我在 Ubuntu 20.04 上快速运行应用程序时,我无法修改 Bash 脚本来添加 JVM 选项。不过,您的建议非常有效。谢谢! 这可行,但不支持小数缩放。所以文字对于我的 1920*1080 屏幕来说太大了。

以上是关于如何在 Windows/Linux 上设置 Java Swing 应用程序的 DPI?的主要内容,如果未能解决你的问题,请参考以下文章

Maven的安装文字版(Windows/Linux/Mac)(转)

【proxy】Linux上各类代理设置

如何在 windows 和 linux 上使用相同的宽字符字符串格式

Windows、Linux和路由器的网络子接口-虚拟IP

Windows/Linux Ubuntu 子系统 Github SSH 设置

如何在 Windows/Mac/Linux 中创建隐藏文件?