OSDN Git Service

java9以降であればリフレクションによるスケールの確認は不要とする。
authorseraphy <seraphy@users.osdn.me>
Mon, 31 Dec 2018 04:45:34 +0000 (13:45 +0900)
committerseraphy <seraphy@users.osdn.me>
Mon, 31 Dec 2018 04:45:34 +0000 (13:45 +0900)
src/main/java/charactermanaj/ui/util/ScaleSupport.java

index 74278f5..097b03d 100644 (file)
@@ -8,6 +8,9 @@ import java.awt.GraphicsEnvironment;
 import java.awt.Toolkit;
 import java.awt.geom.AffineTransform;
 import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import charactermanaj.util.JavaVersionUtils;
 
 /**
  * スクリーンのスケールを取得する。
@@ -21,6 +24,8 @@ public class ScaleSupport {
 
        private static final float computeScale;
 
+       private static final boolean noNeedCheckScaleByReflection;
+
        private double scaleX;
 
        private double scaleY;
@@ -41,6 +46,10 @@ public class ScaleSupport {
                // (Retinaの場合はシステム側でスケールされるのでアプリ側でスケールする必要はないため)
                float dpi = System.getProperty("os.name").startsWith("Windows") ? 96f : resolution;
                computeScale = resolution / dpi;
+
+               // Java9以降であればアフィン変換パラメータでスケールを確認できるので
+               // リフレクションを使ったスケールの確認は不要である。
+               noNeedCheckScaleByReflection = JavaVersionUtils.getJavaVersion() >= 9;
        }
 
        private ScaleSupport(double scaleX, double scaleY) {
@@ -103,26 +112,36 @@ public class ScaleSupport {
                double scaleY = trans.getScaleY();
 
                boolean retina = false;
-               if (scaleX == 1 && scaleY == 1) {
+               if (scaleX == 1 && scaleY == 1 && !noNeedCheckScaleByReflection) {
                        // Java8まではデフォルトのアフィン変換はスクリーンスケールは設定されていないので
-                       // 等倍を返してきた場合は、グラフィクスデバイスがスケーメメソッドをもっているか
-                       // リフレクションで確かめる。Mac版のJava8であればスケーメメソッドをもっている。
+                       // 等倍を返してきた場合は、グラフィクスデバイスがスケールメソッドをもっているかリフレクションで確かめる。
+                       // Mac版のJava8であればスケーメメソッドをもっている。
+                       // (Java9以降であれば確認は不要である。)
+                       // http://hg.openjdk.java.net/jdk9/client/jdk/file/1089d8a8a6e1/src/java.desktop/macosx/classes/sun/awt/CGraphicsDevice.java
                        // https://www.programcreek.com/java-api-examples/?code=SensorsINI/jaer/jaer-master/src/net/sf/jaer/graphics/ChipCanvas.java
                        final GraphicsDevice device = gconf.getDevice();
+                       Object scaleObj = null;
                        try {
-                               Field field = device.getClass().getDeclaredField("scale");
-                               field.setAccessible(true);
-                               Object scaleObj = field.get(device);
-
-                               if (scaleObj instanceof Number) {
-                                       int scale = ((Number) scaleObj).intValue();
-                                       scaleX = scaleY = scale;
-                                       if (scale >= 2) {
-                                               retina = true;
-                                       }
+                               // public methodがあれば、そちらを試す。
+                               Method methodGetScaleFactor = device.getClass().getMethod("getScaleFactor");
+                               scaleObj = methodGetScaleFactor.invoke(device);
+
+                       } catch (Exception ex) {
+                               try {
+                                       // sun.awt.CGraphicsDevice固有の内部フィールドを試す
+                                       Field field = device.getClass().getDeclaredField("scale");
+                                       field.setAccessible(true);
+                                       scaleObj = field.get(device);
+                               } catch (Exception ex2) {
+                                       // 何もしない
+                               }
+                       }
+                       if (scaleObj instanceof Number) {
+                               int scale = ((Number) scaleObj).intValue();
+                               scaleX = scaleY = scale;
+                               if (scale >= 2) {
+                                       retina = true;
                                }
-                       } catch (Exception ignore) {
-                               // 何もしない
                        }
                }
                ScaleSupport inst = new ScaleSupport(scaleX, scaleY);