3 import java.awt.HeadlessException;
4 import java.awt.Toolkit;
6 public class HiDPISetting
8 private static final int hidpiThreshold = 160;
10 private static final int hidpiMultiThreshold = 240;
12 private static final int bigScreenThreshold = 1400;
14 private static final String scalePropertyName = "sun.java2d.uiScale";
16 private static final boolean isLinux;
18 // private static final boolean isAMac;
20 // private static final boolean isWindows;
22 public static final String setHiDPIPropertyName = "setHiDPI";
24 public static final String setHiDPIScalePropertyName = "setHiDPIScale";
26 private static boolean setHiDPI = false;
28 private static int setHiDPIScale = 0;
30 public static int dpi = 0;
32 public static int mindimension = 0;
34 public static int width = 0;
36 public static int scale = 0;
38 public final static int MAX_SCALE = 8;
40 private static boolean doneInit = false;
42 private static boolean allowScalePropertyArg = false;
46 String system = System.getProperty("os.name") == null ? null
47 : System.getProperty("os.name").toLowerCase();
50 isLinux = system.indexOf("linux") > -1;
51 // isAMac = system.indexOf("mac") > -1;
52 // isWindows = system.indexOf("windows") > -1;
57 // isAMac = isWindows = false;
61 private static void init()
68 // get and use command line property values first
69 String setHiDPIProperty = System.getProperty(setHiDPIPropertyName);
70 setHiDPI = setHiDPIProperty != null
71 && setHiDPIProperty.equalsIgnoreCase("true");
73 String setHiDPIScaleProperty = System
74 .getProperty(setHiDPIScalePropertyName);
75 if (setHiDPIScaleProperty != null)
79 setHiDPIScale = Integer.parseInt(setHiDPIScaleProperty);
80 } catch (NumberFormatException e)
82 System.err.println(setHiDPIScalePropertyName + " property give ("
83 + setHiDPIScaleProperty + ") but not parseable as integer");
86 if (setHiDPI && setHiDPIScale > 0)
88 setHiDPIScale(setHiDPIScale);
92 // check to see if the scale property has already been set by something else
94 String existingProperty = System.getProperty(scalePropertyName);
95 if (existingProperty != null)
99 int existingPropertyVal = Integer.parseInt(existingProperty);
100 System.out.println("Existing " + scalePropertyName + " is "
101 + existingPropertyVal);
102 if (existingPropertyVal > 1)
104 setHiDPIScale(existingPropertyVal);
107 } catch (NumberFormatException e)
109 System.out.println("Could not convert property " + scalePropertyName
110 + " vale '" + existingProperty + "' to number");
114 // Try and auto guess a good scale based on reported DPI (not trustworthy)
115 // and screen resolution (more trustworthy)
120 dpi = Toolkit.getDefaultToolkit().getScreenResolution();
121 } catch (HeadlessException e)
123 System.err.println("Cannot get screen resolution: " + e.getMessage());
126 // try and get screen size height and width
129 int height = Toolkit.getDefaultToolkit().getScreenSize().height;
130 int width = Toolkit.getDefaultToolkit().getScreenSize().width;
131 // using mindimension in case of portrait screens
132 mindimension = Math.min(height, width);
133 } catch (HeadlessException e)
136 "Cannot get screen size height and width:" + e.getMessage());
139 // attempt at a formula for scaling based on screen dpi and mindimension.
140 // scale will be an integer >=1. This formula is based on some testing and
143 // scale based on reported dpi. if dpi>hidpiThreshold then scale=2+multiples
144 // of hidpiMultiThreshold (else scale=1)
145 // (e.g. dpi of 110 scales 1. dpi of 120 scales 2. dpi of 360 scales 3)
146 int dpiScale = (dpi - hidpiThreshold > 0)
147 ? 2 + ((dpi - hidpiThreshold) / hidpiMultiThreshold)
150 int dimensionScale = 1 + (mindimension / bigScreenThreshold);
152 // reject outrageous values -- dpiScale in particular could be mistaken
153 if (dpiScale > MAX_SCALE) {
156 if (dimensionScale > MAX_SCALE) {
160 // choose larger of dimensionScale or dpiScale (most likely dimensionScale
161 // as dpiScale often misreported)
162 int autoScale = Math.max(dpiScale, dimensionScale);
164 // only make an automatic change if scale is changed and other conditions
165 // (OS is linux) apply, or if setHiDPI has been specified
166 if ((autoScale > 1 && isLinux) || setHiDPI)
168 setHiDPIScale(autoScale);
172 // looks like we're not doing any scaling
176 public static void setHiDPIScale(int s)
179 allowScalePropertyArg = true;
183 public static String getScalePropertyArg()
186 // HiDPI setting. Just looking at Linux to start with. Test with Windows.
187 return allowScalePropertyArg ? "-D" + scalePropertyName + "=" + scale