[linux] HighDPI環境でJavaアプリケーションをまともな大きさで表示する方法

# Java系のアプリのUIが豆粒で使えない！

僕の高解像度3000x2000ノートPCは、Java(nimbus)を使用していると思われるアプリの画面をうまく表示できません。いえ、画面自体は正しく表示されるのですが、豆粒のように小さなフォントで表示されてしまいます。

今回は、この問題の解決方法と、それまでにやったことをまとめていきます。

## 前提

- ArchLinux(5.4.6-arch1-1)を「gnome3 + wayland」で使用
- `gnome-control-center`の「Displays」設定から「Built-in display」の「Scale」を「200％」に設定している
- gnome標準のアプリやelectron系のアプリでは上の設定に応じて正しいDPIで表示されている

![Javaのghidraやburpsuiteでは表示が豆粒みたいになっていて読めないw](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293301/0d41d844-00c4-4935-0839-982404d6613b.png)

# 結論

1. `java --version`を確認して、JRE/JDK環境がjava8以下の場合はjava9以降を利用する (HiDPI用の実装が含まれているため)
2. 1だけではうまく行かない場合は、環境変数に`GDK_SCALE=2.0`を含めた状態で起動する
3. 「解決策1」のオプションをいろいろ付けて実行してみる
3. 1,2もうまく行かない場合は、アプリ個別に対処するしかなさそう

# やったこと

作業ログのため、取り組んだ順で書いてあります。結論と順番は一致していませんのでご注意ください。

## 解決法1: (失敗)javaにオプションを付けて実行

[How to fix scaling of a java-based application on a high dpi display in linux?](https://stackoverflow.com/questions/58699877/how-to-fix-scaling-of-a-java-based-application-on-a-high-dpi-display-in-linux)を参考にすると

実行時にオプションで

- `-Dsun.java2d.uiScale=2.0`
- `-Dsun.java2d.dpiaware=true`
- `-Dsun.java2d.uiScale.enabled=true`
- `-Dsun.java2d.ddscale=true`

等を追加すればよいとあるのですが、これを`ghidra -Dsun.java2d.uiScale=2.0`や`java -Dsun.java2d.uiScale=2.0 -jar jd-gui.jar`等で試してもうまく行きません。。1つ1つ指定してみたり、複数指定もしてみましたが効果がないようでした。。

## 解決法2: (失敗)GDK_SCALEを使う

次に、[archwikiのHiDPIについての説明](https://wiki.archlinux.jp/index.php/HiDPI#Wayland)を確認してみます。使用しているツール別にHiDPIの適用方法が書いてありました。

Javaで使えるレンダリングエンジンといえばJavaFX,AWTとかが挙げられるわけですが、内部でライブラリとしてGTKを読み込んでいるようです(よく分かってない)

そのため、JavaFXを使っている場合、GDKの設定が適用されるようです。
`export GDK_SCALE=2.0`をしてから実行すると、ghidraでは確かに拡大されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293301/a4c3b0c5-987d-05d7-2548-c532540b0140.png)

しかし、まだ一部しか表示されておらず不具合がありそうです。

ちなみにburpsuiteや手元に会ったjd-guiではこの設定をしても表示の大きさは変わりませんでした。。
実装によるのでしょうか。

## 解決策3: (成功)アプリ個別に設定する

### Ghidra

[Ghidra does not render correctly with GDK_SCALE set (HiDPI display)](https://github.com/NationalSecurityAgency/ghidra/issues/1)

Ghidraの場合、HighDPIの設定について、設定ファイルをイジるように書いてありました。

`/opt/ghidra/support/launch.properties`にある`VMARGS=-Dsun.java2d.xrender=false`をtrueにすればよいようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293301/4efafece-3a57-493a-8fb6-2536bb354e67.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293301/7ffb9210-8c4f-aa00-a542-b6984aa37777.png)

### Burp Suite

[Burp shows super tiny window&letters](https://support.portswigger.net/customer/portal/questions/16981921-burp-shows-super-tiny-window-letters)

Burp Suiteの場合は、設定画面からフォントサイズ等を指定すると改善しました。「User options > Display > User Interface > Font size」

### zaproxy (owasp-zap)

[ZAP doesn't play nice with high-DPI displays](https://github.com/zaproxy/zaproxy/issues/3689)

Java9以降だとうまく行くかもって書いてありました。
`archlinux-java`でopenjdk11に変更すると、普通にいい感じの大きさで表示されました。

### jd-gui

特に情報はありませんでしたが、java11にしたあとに、`GTK_SCALE=2.0`付きで実行したらうまく行きました。この`GTK_SCALE`の実装は汎用的に使えそうです。

## お願い

今回はHighDPIでJavaのアプリケーションを使うなら、とりあえずjava9以降にしとけってことが分かりました。ちゃんと調べていませんが、[これが実装されたおかげ](https://bugs.openjdk.java.net/browse/JDK-8055212)らしいです。

ここまで書いておいてなんですが、実は私、Javaでデスクトップ向けのGUIアプリケーションを書いたことはありません。もし、他の方法をご存知の方はぜひ教えて欲しいです🙏🙏🙏

ご覧いただき、ありがとうございました！！