HiDPI with Eclipse and NetBeans
Learn how to deal with issues for anyone using NetBeans or Eclipse with the new generation of laptops that have extremely high resolution displays on 11, 13 or 15 inch displays.
HiDPI refers to the new generation of high resolution displays. A 4K UHD TV is an example of HiDPI and I assume that if you want to sit in front of a 60 inch or 150 cm display then what I am writing about is not of interest to you. This is an issue for anyone with the new generation of laptops that have extremely high resolution displays on 11, 13 or 15 inch displays.
Apple and Microsoft
Apple were the first to make HiDPI displays standard in their product line and they called it Retina. Currently the 13” MacBook Pro has a HiDPI of 2560 pixels x 1600 lines and the 15” model has 2880 pixels x 1800 lines. This set off an arms race between manufacturers to come up with either matching or greater resolutions.
Microsoft’s Surface Pro 3 has a HiDPI of 2160 pixels x 1440 lines. Lenovo, Fujitsu, Samsung and Dell all have laptops that have a HiDPI of 3200 pixels x 1800 lines. I was fortunate to get a Dell XPS 13 with the HiDPI display just this week.
Changing the Writing of Software
My 3200 pixels horizontal resolution display is approximately 11 ½ inches wide. If I divide the resolution by the width I get a pixels per inch of approximately 278. That’s pretty amazing and results in a magnificent display. The problem is that much of the software we use today has been written to assume a ppi of 72 – 96. On my 27” desktop display with a horizontal resolution of 1920 pixels this works out to a ppi of 88. This means that menus, dialogs and windows are nice and large and easy to see. On my 4 day old Dell XPS these same elements are almost microscopic in size. The worst are the bitmap, png or jpg icons, many of which are 16 x 16 or maybe 32 x 32 pixels and so are near invisible.
The solution to this problem is to change how we write software. Default sizes must be calculated as a percentage of the ppi rather than a fixed ppi value. Icons should be at least 256 x 256 pixels and then scaled by the application based on the system ppi. Even better is to use scalable vector graphics or SVG for images. However, software is only just now being written for this ecosystem of HiDPI displays. But what about legacy software or software just not written for HiDPI?
Legacy Software and Scaling
Mac OSX 10.7 and later and Microsoft Window 8 and now Windows 10 employ a technique called scaling to deal with software that has not been written for HiDPI displays. Scaling enlarges the application by a percentage to make it usable and not microscopic. An early approach to scaling was akin to putting the application under a magnifying glass. The problem with this is that text and images can appear fuzzy and not sharp.
Current scaling techniques in Windows 10, and I don’t have a Retina Mac to comment on, use a scaling technique where font sizes are increased and so the text is sharp. Images can still be a problem but the scaling algorithms in Windows 10 do a pretty good job. The size of containers such as dialogs are nicely scaled as well.
That should be that but unfortunately it’s not. It turns out that an application can refuse to scale. This is the problem that led me to this article. The two most important applications that I use, as a teacher in the classroom, are NetBeans and Eclipse. They both default to ignoring the scaling. Here then are the solutions for these two programs. The solution for Eclipse may likely be applicable to any Windows application that ignores scaling but I have not tested this theory.
NetBeans 8.02 & 8.1 Beta
This is my personal choice for an IDE and what I use for most of the code I develop for my courses, regardless of the IDE the students will use. When I started up NetBeans on my XPS it was unusable. Despite the fact that Windows 10 uses a scaling factor of 250%, the text and icons were too small to read.
I did what every intelligent developer does and went to my search engine, Google, to see if anyone else had the problem and to find how they solved it.
The first solution I came across was the suggestion to use the command line switch –fontsize. Using this sets the minimum font size for all text in the program. One big problem, the size of containers of text such as dialog boxes, menus or titles in tabbed windows do not increase in size appropriately to support the larger font. In other words, NetBeans does not scale internally based on the font. NetBeans is very granular when it comes to font sizes, giving you the ability to change font and size for many of its components. If you significantly increased the size of fonts, say by 50 %, then the dialogs boxes and other font container become unusable.
Let’s assume for a minute that changing the font size worked. This solution would not have worked for me. I use my laptop in the class to connect to a projector. When I do this I mirror my screen to the projector and most of these max out at 1280 x 1024. If I used –fontsize I’d end up with text that is too large. I could have multiple shortcuts, each with a different –fontsize, but inevitably this would prove to be unwieldy. What if I have access to a projector for a resolution I have not created a shortcut for. Then of course there would be the embarrassment of using the wrong shortcut. There is nothing like looking technically inept in front of students.
The second solution I found here:
This one, the one that worked, dealt with a specific switch for NetBeans found in \etc\netbeans.conf.
Here is the entire line in its default form:
netbeans_default_options="-J-client -J-Xss2m -J-Xms32m -J-XX:PermSize=32m -J-Dapple.laf.useScreenMenuBar=true -J-Dapple.awt.graphics.UseQuartz=true -J-Dsun.java2d.noddraw=true -J-Dsun.java2d.dpiaware=true -J-Dsun.zip.disableMemoryMapping=true"
Notice the switch
-J-Dsun.java2d.dpiaware=true. A quick search only talks about it when using Windows Vista. If you know what its real purpose is then let me know. The solution to the scaling problem for NetBeans is to set this property to false. It now scales as expected and the program displays correctly at all resolutions.
Note: You must be running NetBeans from netbeans64.exe and not from netbeans.exe.
Eclipse Mars (and probably earlier versions)
If you haven’t read the NetBeans section then go back and read it. That’s because Eclipse does not scale just like NetBeans and for what appears to be a similar reason, it ignores scaling.
The solution is not the same because while NetBeans is a Swing application Eclipse is an SWT application. Therefore there is no comparable switch dealing with dpi awareness. It can have its font sizes changed but that works as well or as badly as NetBeans.
I found the solution in an Eclipse bug report. The report is Bug 421383 – [Graphics] Scaling issues on high DPI displays and was first reported in November 2013 and last commented on in July 2015. There are 84 comments on this bug but the solution, by way of a work around, was proposed by Matthew Cochrane on March 2, 2015.
Matthew knew or discovered that a manifest file can be used to modify the run time environment of a Windows application. The solution involves adding a registry entry because Windows will ignore a manifest file. The first step is add a registry entry to support external manifest files.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\SideBySide\PreferExternalManifest (DWORD) to 1
Next, a manifest file with the same name as the executable must be present in the same folder as the executable. The file is named
eclipse.exe.manifest and consists of:
<?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"> <description>eclipse</description> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> <security> <requestedPrivileges> <requestedExecutionLevel xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3" level="asInvoker" ms_asmv3:uiAccess="false"> </requestedExecutionLevel> </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>
Notice the line
Here is the result:
I suspect, without having tested it, that this solution may work for any Windows applications that might ignore scaling on a HiDPI display.
For a few hours I had serious doubts about my choice of the Dell XPS. It was replacing an Early 2011 MacBook Pro that had a resolution of 1280 x 800. As you can imagine I never had a scaling issue with this. Now that I have a solution and a repeatable solution I have returned to my state of bliss with my new laptop.