75

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

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

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

4

6 回答 6

39

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

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

一个例外是 System 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

于 2013-05-08T08:13:38.103 回答
12

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

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

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

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

于 2017-07-31T23:58:47.927 回答
6

这个答案解决了我的 4K 屏幕 Ubuntu 笔记本电脑上的问题。

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

于 2020-08-05T11:22:59.300 回答
3

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

.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 "$@"
于 2016-01-23T16:23:18.660 回答
3

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

export GDK_SCALE=2

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

于 2020-11-28T08:49:08.363 回答
2

我设法按照以下说明解决了它: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.manifestand javaw.exe.manifest(您将拥有两个内容相同但名称不同的文件)。

HTH。

伯恩德

于 2016-12-27T19:03:29.413 回答