JFormDesigner / FlatLaf

FlatLaf - Swing Look and Feel (with Darcula/IntelliJ themes support)
https://www.formdev.com/flatlaf/
Apache License 2.0
3.45k stars 274 forks source link

Installing FlatLaf disables antialiasing on Windows #307

Closed uwemock closed 2 years ago

uwemock commented 3 years ago

I'm doing the following to enable antialiasing in my Swing application:

System.setProperty("awt.useSystemAAFontSettings","on"); System.setProperty("sun.java2d.xrender", "true");

When I do this after installing FlatLaf in the UIManager, everything is fine. When I install FlatLaf after setting the two properties, antialiasing is reported not to work properly on Windows (see attached screenshot).

Screenshot 2021-04-14 140554

Is there any reason for this behaviour? Anything on can do to prevent it (except getting the sequence right)?

CC: @mbiebl

DevCharly commented 3 years ago

Well, both windows use antialiasing, but different kind of antialiasing.

image

Left window uses "lcd" antialiasing (the default on Windows). Right window uses "grayscale" antialiasing, which you specified with awt.useSystemAAFontSettings=on.

So everything works as expected.

When I do this after installing FlatLaf in the UIManager, everything is fine.

Because in this case FlatLaf already initialized the antialiasing used in FlatLaf. (awt.useSystemAAFontSettings=on is ignored)

When I install FlatLaf after setting the two properties, antialiasing is reported not to work properly on Windows.

Because in this case FlatLaf uses "grayscale" antialiazing, as specified with awt.useSystemAAFontSettings=on.

Anything on can do to prevent it

Do not use awt.useSystemAAFontSettings with FlatLaf. It is not necessary. Even for Metal, Nimbus and Windows L&F, this is not necessary.

(or at least use awt.useSystemAAFontSettings=lcd on Windows. Don't know whether this works on Linux or macOS)

uwemock commented 3 years ago

Because in this case FlatLaf already initialized the antialiasing used in FlatLaf. (awt.useSystemAAFontSettings=on is ignored)

Shouldn't FlatLaf do this only in case I enable it as the current L&F?

at least use awt.useSystemAAFontSettings=lcd on Windows

I experimented with this setting, but I thought it is obsolete as it showed no effect. On my screen, everything looks exactly as with "on". When I leave the setting out, some people will complain about dodgy fonts.

DevCharly commented 3 years ago

When I do this after installing FlatLaf in the UIManager, everything is fine.

Because in this case FlatLaf already initialized the antialiasing used in FlatLaf. (awt.useSystemAAFontSettings=on is ignored)

Shouldn't FlatLaf do this only in case I enable it as the current L&F?

Yes, this is what I said.

at least use awt.useSystemAAFontSettings=lcd on Windows

I experimented with this setting, but I thought it is obsolete as it showed no effect. On my screen, everything looks exactly as with "on". When I leave the setting out, some people will complain about dodgy fonts.

On Windows? To my knowledge this can happen only if the user disabled antialiasing in Windows settings. But then all text on Windows do not use antialiasing...

uwemock commented 3 years ago

The problem is that the only documented call that installs FlatLaf, FlatLightLaf.install(), not only installs to the L&F to the UIManager, it also activates the L&F at the same time and this might change settings that have been made before.

By looking at the source code, I found that there is FlatLightLaf.installLafInfo() which only installs the L&F without activating it. I strongly suggest that this method be documented on the website along with the other one.

I also could not find JavaDoc for FlatLaf. JavaDoc should be available on the website.

DevCharly commented 3 years ago

Regarding the antialiasing problem: I suggest following solution:

if( Toolkit.getDefaultToolkit().getDesktopProperty( "awt.font.desktophints" ) == null ) {
    System.setProperty("awt.useSystemAAFontSettings","on");
}

This sets the system property only if antialiasing is not already enabled and should work on all platforms.

The problem is that the only documented call that installs FlatLaf, FlatLightLaf.install(), not only installs to the L&F to the UIManager, it also activates the L&F at the same time and this might change settings that have been made before.

Yes, the naming of FlatLightLaf.install() was not the best decision. I think this naming was inspired by other 3rd party Lafs that also use an install() method. At some point I realized that this is confusing with UIManager.installLookAndFeel(LookAndFeelInfo info) and added FlatLightLaf.installLafInfo().

Maybe I should rename FlatLightLaf.install() to something better (and keep the original method as deprecated for some versions).

Maybe FlatLightLaf.setup()? Any better ideas?