Как настроить DPI приложений Java Swing для Windows/Linux?
Если у вас есть монитор с DPI более 150 (например, Macbook Pro), вы также можете найти проблему: шрифт в приложении Java Swing слишком мал для монитора с высоким DPI, и я вообще не могу изменить размер шрифта (напрямую игнорирует Windows DPI, отображая только оригинальное DPI -> 96). Я ничего не могу сделать, кроме изменения разрешения экрана, которое может сделать все размытое на ЖК-дисплее.
Да, у меня есть ноутбук с монитором с высоким DPI, 15,6 дюйма с разрешением 1920x1080, некоторые настольные приложения Java выглядят очень маленькими на моем ноутбуке, такие как Matlab, Burpsuite и т. Д. Я очень долго искал в Интернете, но до сих пор не могу найти способ решения проблемы. Я знаю, что могу изменить шрифты JRE через JRE_HOME/lib/font/fontconfig.properties.src
, но я не могу найти место для установки размера шрифта по умолчанию или DPI для шрифтов рабочего стола Java.
У проблемы нет решения? У вас есть монитор с высоким DPI? Как вы делаете с такими приложениями? Отказывается ли Swing от пользователей с высоким DPI?
7 ответов
В настоящее время я изучаю эту проблему в Windows. Вот что я нашел:
Большинство Swing Look & Feels вообще не поддерживают высокий DPI, даже Nimbus, хотя он должен быть масштабируемым. Я нашел несколько старых постов в блоге, в которых говорилось, что Nimbus может в конечном итоге предложить масштабирование с высоким разрешением, но, очевидно, этого не произошло.
Единственным исключением является System LAF, но его шрифт по умолчанию на ~10% меньше, чем фактический размер системного шрифта, при всех настройках DPI. Кроме того, Система должна быть выбрана явно, как описано здесь: http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
Там нет ни одного масштабного коэффициента, который вы могли бы установить в Swing, либо. Конкретный LAF должен предоставить код для обработки масштабирования. Поэтому лучшее, что вы можете сделать, это выбрать Систему и надеяться, что она достаточно хороша.
Тем не менее, JavaFX правильно и автоматически масштабируется до 150% в моей системе. Если это вообще возможно, я предлагаю вам использовать JavaFX для создания своего GUI.
редактировать: я сделал пару небольших тестовых программ и сделал сравнительные снимки экрана для различных структур графического интерфейса, тем Swing и настроек DPI. Это может быть полезно для людей, читающих этот вопрос: http://kynosarges.org/GuiDpiScaling.html
Краткий ответ: Вам нужно запустить его на JRE 9.
Длинный ответ:
Это связано с тем, что среда выполнения Java объявила себя "поддерживающей DPI", но на самом деле не поддерживала ее для AWT и Swing. Java-приложения были измерены и отображены на основе пикселей, а не должным образом масштабированы, это включало дисплеи HiDPI. В любом случае, это было недавно решено. См. Выпуск JEP 263. Графика HiDPI в Windows и Linux и обновление.
Таким образом, увеличение размера шрифта не работает (потому что это не увеличивает все остальное); аргумент JVM -Dsun.java2d.dpiaware=false
не работает (потому что это не очень поддерживается); и файл манифеста + редактирование реестра (для Windows) просто не работает.
Решение: вам нужно запустить его на JRE 9, потому что он действительно поддерживает эту функцию.
Этот ответ решил проблему на моем ноутбуке Ubuntu с экраном 4K.
В конфигурационном файле приложения я добавил -Dsun.java2d.uiScale=2.5
Параметр Java, и теперь после выполнения приложение хорошо масштабируется и его можно использовать.
Похоже, что в Linux (Gtk) вы можете обойти это, масштабируя DPI приложений, используя следующее перед запуском приложения.
export GDK_SCALE=2
(Вы также можете уменьшить разрешение монитора, но это вообще не решение).
В Linux, по моим экспериментам, невозможно выполнить масштабирование с использованием внешнего вида Swing. Тем не менее, это можно сделать, используя хак с использованием VNC, 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 "$@"
Мне удалось решить это, следуя этим инструкциям: Ссылка.
Это на немецком языке, но я переведу важные вещи.
Создайте этот ключ реестра:
[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>
Скопируйте его в каталог bin, где находятся java.exe и javaw.exe и назовите его java.exe.manifest
а также javaw.exe.manifest
(У вас будет два файла с одинаковым содержимым, но разными именами).
НТН.
Бернд
Как сказал @demented hedgehog, устанавливаяGDK_SCALE=2
переменная окружения работает под Linux.
Если вы используете JetBrains IntelliJ, вы можете установить переменные среды только для своего проекта в разделеEdit configurations > Build and Run > Enviroment variables
Ниже вы можете увидеть, куда поместить GDK_SCALE=2.