この記事は、JavaFX Advent Calendar 2017の3日目です。2日目はHASUNUMA Kenjiさんのafterburner.fx によるお手軽 JavaFX プログラミング (1)です。

JavaFXのHiDPIに関する現状と設定についての簡単なメモです。

標準的なディスプレイは96DPI(Dots Per Inch:96DPIは、1インチに96画素)、1画素の大きさは0.264mmとなります。
一方、超高解像度なディスプレイは、例えば13.3インチで2560×1440画素の場合、220DPIで1画素の大きさは0.11mmとなります。

12ピクセルの文字は、標準的なディスプレイでは3.2mmの大きさとなりますが、超高解像度なディスプレイでは1.4mmの大きさとなります。

超高解像度なディスプレイではこのように画面に表示されるものの大きさが、標準ディスプレイでは半分未満に小さくなってしまい、不都合が生じます。この対処として、OSの機能で画面に表示されるものの大きさを拡大します。Windows 10 OSの場合は、ディスプレイの設定で「テキスト、アプリ、その他の項目のサイズを変更する」を150%、175%、200%などに変更可能です。

JavaFXでは、JDK 8の最新版、JDK 9において、Windows環境ではこのディスプレイのサイズ変更の拡大率をもとに表示の大きさを変えるようになっています。

例えば、AnchorPaneのPref WidthとPref Heightを320、200に、フォントの大きさを12pxに設定した画面を超高解像度ディスプレイに表示すると、OSの設定でサイズを変更するの値に応じて拡大して表示されます。

この拡大を抑制し、本来のディスプレイの物理的な解像度にJavaFXのピクセル設定を合わせるには、システムプロパティprism.allowhidpiをfalseに設定します。

以下に、システムプロパティprism.allowhidpiをtrue(デフォルト)とfalse に設定した場合の画面の大きさを並べて示します。

image.png

システムプロパティprism.allowhidpiの設定を変えたグラフィックス表示の場合の大きさを並べて示します。

image.png

getDpi()によるDPI値の取得

JavaFXにはディスプレイのDPI値を取得するAPIが用意されています。
javafx.stage.ScreenクラスのgetDpi()メソッドです。

13.3インチで2560x1440の解像度のディスプレイ上で、Windows OSのディスプレイのサイズ変更が150%に設定されている環境で、このAPIを使ってDPI値を取得した結果の例が次となります。

OSのディスプレイ設定のサイズ変更値 prism.allowhidpiの値 getDpi()の結果
150% true 147.0
150% false 221.0