2

I help maintain a large, very old Swing project. We noticed that the swing project pages running under JRE 11 look quite a bit different from the swing project running under JRE 8, our previous version.

I have been exploring this issue. One thing I noticed is that basic sizing seems to be different. JRE11 makes all the JFrames larger. We need to have the sizing stay consistent.

Here is a small program to demonstrate what I am seeing:

    import javax.swing.*;

public class JustAFrame
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(
                () -> {
                    JFrame frame = new JFrame();
                    frame.setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE );
                    frame.pack();
                    frame.setSize(400, 500);
                    frame.setVisible(true);
                });
    }
}

I ran this program on the same Windows 10 machine using java 64 bit version jdk1.8.0_241 and zulu11.41.23-ca-fx-jdk11.0.8-win_x64. I'm attaching an image showing the same class running in the two java versions side by side. The JRE 11 version appears to be about 50% larger. What can I do to make the JRE 11 JVM make our JFrames the size as our previous version of java, without having to go into every JFrame instance in our application and fiddling with the size Dimension parameter?

enter image description here

Warren
  • 179
  • 2
  • 7
  • Looks like a bug... I was unable to reproduce it on my machine and you set the size in your code. Did you try it with other OpenJDK 11 builds? – sb27 Oct 22 '20 at 19:26
  • Is there any display resolution scaling going on? – Jim Garrison Oct 22 '20 at 19:34
  • *"The JRE 11 version appears to be about 50% larger."* Not to my eye it doesn't. Not 50% in any case. Why not pin it down a bit by printing the `java.version` and the size of the frame (as returned by the JRE running it) & content pane for each run? As an aside, it is folly to try and expect a consistent frame size. The important thing is that custom components that do rendering are a consistent size and the frame packed to fit them. – Andrew Thompson Oct 22 '20 at 19:42
  • @sb27: I just tried switching to another java version. This one "Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.7+8-LTS, mixed mode)" with the same result. – Warren Oct 22 '20 at 21:48
  • @Jim Garrison: Not sure what you mean by 'display resolution'? Can you be more specific? Thanks. – Warren Oct 22 '20 at 21:49
  • @Andrew Thompson: yes, I thought someone would point out that it wasn't exactly 50% larger. But, you can see that the difference is notable. I think what you are saying is that there is no way to make frame size resolution consistent across java versions. That is a shame, because I would like to have some assurance that a unit in the Dimensions class for width or height means the same thing, not matter what JVM I am running. I'd also note that there does not seem to be a size discrepancy between java 1.7 running the same class (with no Lambda) and java 1.8. – Warren Oct 22 '20 at 21:56
  • *and fiddling with the size Dimension parameter?* - you should not need to fiddle with the size dimensions. Swing was designed to be used with layout managers and should handle the size/location of components for you. – camickr Oct 23 '20 at 00:20
  • More on this: I ran the code above on another machine, running WIndows 7, using the two JREs. Now the JFrame size is the same. – Warren Oct 23 '20 at 17:06
  • It looks like you are using windows 10 so as mentioned, try changing your display scaling to see what effect that has: settings/system/display/scale and layout. – NickD Oct 24 '20 at 13:50
  • 2
    This is most definitely caused by display scaling. Pre java 8 one unit of the dimension always corresponded to one pixel on the screen. However with java 9 high-dpi scaling was added which results in one unit corresponding to more than one pixel based on the scale factor. In your case it looks like you are using 125% scaling. Thus the frame is larger. – weisj Oct 25 '20 at 10:36
  • @weisj Thank you for the explanation. That sounds like it may be what I'm looking for. However, is there any way to standardize the appearance without writing something to adjust the requested size() for the JFrame based on the hardware and JVM it is running on? – Warren Oct 27 '20 at 00:47
  • Is there a reason you need to have a precise frame size? I would recommend to always rely on using appropriate LayoutManagers and let the frame decide it’s preferred size itself through Frame#pack. But if you really need to set the precise size you could either bundle the application with a JDK version >=9 as the simplest solution. Otherwise you could get the GraphicsConfigurarion of the frame and retrieve its DefaultTransform. The scaling of this transform determines the scaled size. – weisj Oct 27 '20 at 11:35

1 Answers1

2

This is due to after Java 9, windows scaling compatibility working correctly.
that means if your monitor is set to scale at 150%, the Java application is scaled to 150%. to disable this, use the following methods (worked for me in zulu11)

set VM option : -Dsun.java2d.uiScale=1.0

OR

System.setProperty("sun.java2d.uiScale", "1.0");

1.0 = 100%

Akila
  • 1,258
  • 2
  • 16
  • 25