kirill-grouchnikov / substance

A modern and high-performant Swing look-and-feel library
163 stars 110 forks source link

Pixelated components when using Java 9 w/ HiDPI #48

Closed utybo closed 6 years ago

utybo commented 7 years ago

Since Java 9 added HiDPI compatibility, all components (such as arrows, buttons, tabs...) in Substance look pixelated.

This is probably caused by some conflict between Substance's implementation of HiDPI and Swing's new HiDPI features.

kirill-grouchnikov commented 7 years ago

I'll need much more information than this.

What is the version of Substance? What is the OS and the version of the OS? What is the version of Java?

Also, please attach screenshots of the same UI under Java 8 and Java 9 on that machine.

utybo commented 7 years ago

image

Here is an image of the issue. On the left, with Java 8 (latest version), on the right, Java 9 (9.0.1). You can clearly see the edges of the components are not scaled properly in Java 9.

As for the OS, I'm using Windows 10, with a 125% scaling factor. Test done with Substance 7.1

Here is the code :


        SwingUtilities.invokeLater(() ->
        {
            try
            {
                UIManager.setLookAndFeel(new SubstanceBusinessLookAndFeel());
            }
            catch(UnsupportedLookAndFeelException e)
            {
                e.printStackTrace();
            }

            JFrame frame = new JFrame();
            JTabbedPane jtp = new JTabbedPane();
            JPanel pan = new JPanel();
            pan.add(new JButton("Hello!"));
            jtp.addTab("Testing", pan);
            frame.add(jtp);
            frame.setSize(300, 200);
            frame.setVisible(true);

        });
utybo commented 7 years ago

As a side note, this issue also occurs when choosing the 150% scaling factor in Windows 10

kirill-grouchnikov commented 7 years ago

For now, use –Dsun.java2d.uiScale=1.0 on Java 9 to disable the built-in HiDPI emulation on Java 9 when the desktop is using a custom scaling factor.

I will look into whether it is feasible to provide support for HiDPI on both Java 8 and Java 9.

utybo commented 7 years ago

Alright, thanks for the workaround. Keep up the great work! :)

utybo commented 6 years ago

After testing the workaround you provided, it looks like fonts are not scaled with said workaround. Everything else works, but icons seem to not be scaled at all and, because of this, appear tiny.

utybo commented 6 years ago

This fixes the text scaling issues when using the workaround. Use this after applying the LaF :

SubstanceLookAndFeel.setFontPolicy(SubstanceFontUtilities.getScaledFontPolicy(
                    (float)(SubstanceSizeUtils.getPointsToPixelsRatio()) / 1.33F));

Just to recap for anyone who encounters the same bug : the current way to get Substance to work nicely with HiDPI on Java 9 is to use -Dsun.java2d.uiScale=1.0 to disable the Java 9 HiDPI system, and the code snippet above to fix font scaling.

kirill-grouchnikov commented 6 years ago

Thank you. I've added that snippet at the end of https://github.com/kirill-grouchnikov/substance/blob/master/www/docs/faq.md

utybo commented 6 years ago

The snippet has a problem though, in that now all the fonts are way bigger when using Java 8.

Edit : If compatibility with both Java 8 and Java 9 is required, one can simply run the snippet under the following if :

if(new JLabel("a").getFont().getSize() <= 12)

Kind of a hack, but it works. If the font is small, it is considered to not be scaled, then the scaling mechanism is applied. In this way, if the font was already scaled, the snippet isn't run, and if it wasn't scaled, the snippet is ran. In case of normal HiDPI, then it doesn't really matter, as it will just get a scaled policy that is scaled by 100% (i.e. actually not scaled).

kirill-grouchnikov commented 6 years ago

That can be "guarded" by checking the Java runtime version.

System.getProperty("java.specification.version").startsWith("9")

Of course, you wouldn't know the custom scaling factor set on the particular machine without yet more code.

utybo commented 6 years ago

The problem is that i am also encountering issues with fonts not being scaled under other very specific circumstances I won't investigate further. (e.g using packr to create a .exe with an embedded JRE under Java 8. Substance doesn't scale fonts for an obscure unknown reason.)

So this is kind of a universal fix for any "font not being scaled" problem. I will open other issues if I manage to find the specific causes for this kind of problem.

EDIT : After doing some tests the scaling issues are not caused by Substance but by a weird bug in packr. So your guard is much better in most cases.

kirill-grouchnikov commented 6 years ago

This is ready for testing. There are a few "corners" where the visuals under fractional scaling factors are not quite perfect. Some of those will be addressed in time for the final 8.0.0 release, and those that slip will be handled a bit later.