← Back to team overview

openjdk team mailing list archive

[Bug 1581835] Re: Native Look and Feel for Swing does not work

 

tl;dr Drop the
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()) call
if you want to use the swing.defaultlaf as the System LAF is hardcoded
and selected by heuristics and swing.properties can't do anything about
it.


I took a look at the UIManager.java yesterday to get a picture of what
is going on and there are a few misunderstandings going on with how
UIManager deals with LAF selection.

The file in question is
http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/tip/src/share/classes/javax/swing/UIManager.java

Before we go ahead, let me just even the field with a few LAF concepts
and heuristics.

= The Cross Platform LAF =
It is not possible to change the cross platform LAF through swing.properties, UIManager will either use what is set through system properties (-D in command line or _JAVA_OPTIONS) or the hardcoded setting (Metal for both JDK7u and JDK8u as of Today). 
References: 
http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/tip/src/share/classes/javax/swing/UIManager.java#l642
http://hg.openjdk.java.net/jdk7u/jdk7u-dev/jdk/file/tip/src/share/classes/javax/swing/UIManager.java#l639

= How OpenJDK decides the right default LAF =
1. Non-null swing.defaultlaf system property
2. swing.defaultlaf set in swing.properties
3. the cross platform LAF

References, see section "Default look and feel":
https://docs.oracle.com/javase/8/docs/api/javax/swing/UIManager.html
https://docs.oracle.com/javase/7/docs/api/javax/swing/UIManager.html

= UIManager.getSystemLookAndFeelClassName() =
Javadoc states "Returns the name of the LookAndFeel class that implements the native system look and feel if there is one, otherwise the name of the default cross platform LookAndFeel class."

This call will actually try to:
1. Read the system property swing.systemlaf if set, or
2. Select a *hardcoded* value according to running OS and desktop, or
3. Defaults to the *cross platform LAF* if nothing matches. 

Yes, it ignores the default LAF altogether.

On Linux it will return GTK LAF if and only if the property
"sun.desktop" is set to "gnome" and the internal SunToolkit detects GTK
as being available, otherwise it will default to the Metal cross
platform LAF.

Again: *System LAF completely ignores the Default LAF settings.*

References:
http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/tip/src/share/classes/javax/swing/UIManager.java#l600
http://hg.openjdk.java.net/jdk7u/jdk7u-dev/jdk/file/tip/src/share/classes/javax/swing/UIManager.java#l597

= PDF Merger LAF issues =
PDFMerger is forcing the usage of the System LAF through the call to UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()).

In order for swing to actually use the default LAF, that call must be
removed.

There are 4 other alternatives to get the GTK LAF while still keeping that call:
1. Set the system property swing.systemlaf (through -D on command line or _JAVA_OPTIONS)
1. Set the system property swing.crossplatformlaf (-D as above)
2. Set the system property sun.desktop=gnome (-D as above), will only work if GTK is detected by SunToolkit
3. Set the property swing.installedlafs as a system property or in swing.properties (this forces UIManager to use GTK as no other LAF will be available to it)

The initial _JAVA_OPTIONS only worked because of the
swing.crossplatformlaf setting being selected as the System LAF, if that
setting is dropped then PDFMerger will use Metal. By the same reasoning
swing.defaultlaf could be easily dropped as it had no effect whatsoever
(system laf ignores it). Also, as swing.crossplatformlaf is not read
from the swing.properties file, PDFMerger ended up with Metal when
-Dswing.crossplatformlaf is not set to something else.

= Summary =
Calling UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()) should be avoided as it ignores the default LAF and it is not easy to workaround it system-wide. On Linux this call will only use the GTK native LAF on gnome systems.

Possible improvements would be to request OpenJDK to allow the system
and/or cross platform LAF to be set on swing.properties or improve the
heuristics of the system LAF selection to work on non-"gnome" desktops.
The best approach fro this is to discuss it on the OpenJDK mailing list
(http://mail.openjdk.java.net/mailman/listinfo/discuss is a good start).

Thank you for reading it all the way. ;-)

-- 
You received this bug notification because you are a member of OpenJDK,
which is subscribed to openjdk-7 in Ubuntu.
https://bugs.launchpad.net/bugs/1581835

Title:
  Native Look and Feel for Swing does not work

Status in openjdk-7 package in Ubuntu:
  Invalid
Status in openjdk-8 package in Ubuntu:
  Invalid

Bug description:
  Openjdk-7 and openjdk-8 do not enable native look and feel by default. But they support it. Apps use ugly blue theme, even if the code contains "UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());"
  I've tried Xubuntu 14.04, Ubuntu Mate 16.04 - apps look ugly. (for example logisim)

  To get native LAF you need to use these arguments: _JAVA_OPTIONS 
  -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true -Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel -Dswing.crossplatformlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/openjdk-7/+bug/1581835/+subscriptions


References