Java in Linux - different look and feel classes for root and non-root

|▌冷眼眸甩不掉的悲伤 提交于 2020-01-03 12:25:11

问题


I noticed that Java proposes different look and feel classes for root and non-root users. I am trying to understand how to make LAF consistent. Moreover, it's inconsistent even within a user/root: depends on how user/root logged in:

Sample code (compiled and packaged in laf.jar):

import javax.swing.UIManager;

public class laf {
    public static void main(java.lang.String[] args) {
        try {
            System.out.print(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
        }
    }
}

Scenario 1 Logs in to machine (in GUI mode) as a regular user

Sample output (as user)

[xxx@yyy Downloads]$ java -classpath laf.jar laf
com.sun.java.swing.plaf.gtk.GTKLookAndFeel

Sample output (switch to root via su)

[root@yyy Downloads]# java -classpath ./laf.jar laf
javax.swing.plaf.metal.MetalLookAndFeel

Scenario 2 Logs in to machine (in GUI mode) as root

Sample output (as root)

[root@yyy Downloads]# java -classpath ./laf.jar laf
com.sun.java.swing.plaf.gtk.GTKLookAndFeel

Scenario 3 Logs in to machine via SSH as a regular user (similar as scenario #1 above, but in this case - same LAF)

Sample output (as user)

[xxx@yyy Downloads]$ java -classpath laf.jar laf
javax.swing.plaf.metal.MetalLookAndFeel

Sample output (switch to root)

[root@yyy Downloads]# java -classpath ./laf.jar laf
javax.swing.plaf.metal.MetalLookAndFeel

Software versions:

[root@yyy Downloads]# java -version
java version "1.7.0"
Java(TM) SE Runtime Environment (build pxa6470sr9fp10-20150708_01(SR9 FP10))
IBM J9 VM (build 2.6, JRE 1.7.0 Linux amd64-64 Compressed References     20150701_255667 (JIT enabled, AOT enabled)
J9VM - R26_Java726_SR9_20150701_0050_B255667
JIT  - tr.r11_20150626_95120.01
GC   - R26_Java726_SR9_20150701_0050_B255667_CMPRSS
J9CL - 20150701_255667)
JCL - 20150628_01 based on Oracle jdk7u85-b15

[root@yyy Downloads]# cat /etc/redhat-release 
Red Hat Enterprise Linux Workstation release 6.7 (Santiago)

回答1:


The first line of getSystemLookAndFeelClassName is:

public static String getSystemLookAndFeelClassName() {
    String systemLAF = AccessController.doPrivileged(
                         new GetPropertyAction("swing.systemlaf"));

So you can use the JAVA_OPTS of the user to set

-Dswing.systemlaf=javax.swing.plaf.metal.MetalLookAndFeel

As default.

add this to the .rc-File of the user:

set JAVA_OPTS=-Dswing.systemlaf=javax.swing.plaf.metal.MetalLookAndFeel
export JAVA_OPTS

Regards




回答2:


This is less about root, and more about environment variables.

Basically, the UIManager.getSystemLookAndFeelClassName method works like this:

  • Check the swing.systemlaf system property. This allows the user to override whatever the system wants to choose. If it is not null, it's used.
  • Otherwise, if the operating system is Windows, it returns the WindowsLookAndFeel.
  • Otherwise, it checks the sun.desktop property. If sun.desktop is set to gnome, and GTK is available natively, it returs the GTKLookAndFeel
  • Otherwise, checks for Mac OS X and Solaris and returns appropriate values for these operating systems.
  • If all other checks failed, it returns the "cross platform" L&F, which is MetalLookAndFeel.

So, the part that is relevant to Linux/Unix is the part that checks sun.desktop. This property is set when the JVM starts up. It is set to gnome if the environment variable GNOME_DESKTOP_SESSION_ID exists, ignoring its contents, and it is set to null otherwise. I believe this is the pertinent native source code that does this.

So, on Linux, if that environment variable is set (and GTK is available), your L&F will be set to GTKLookAndFeel. If not, it will be set to MetalLookAndFeel.

When you log in to a Gnome-based Linux using the desktop manager, your environment will have that variable set. But the su command does not propagate environment variables by default. Thus, when you su to any user, not necessarily root, you lose the GNOME_DESKTOP_SESSION_ID environment variable, and Java will default to MetalLookAndFeel.

You can cause your environment to be passed through su by using su -p, or if you are using sudo, using sudo -E.

The ssh command, like su and sudo, does not propagate environment variables. This can also be worked around using ~/.ssh/environment.

However, as already stated - you can easily force a specific L&F by passing the -Dswing.systemlaf=... switch to the java command.



来源:https://stackoverflow.com/questions/33735981/java-in-linux-different-look-and-feel-classes-for-root-and-non-root

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!