Linux中的Java-根和非根的不同外观类

Linux中的Java-根和非根的不同外观类,java,linux,redhat,look-and-feel,Java,Linux,Redhat,Look And Feel,我注意到Java为根用户和非根用户提供了不同的外观类。我试图理解如何使LAF保持一致。此外,即使在用户/根目录中也不一致:取决于用户/根目录的登录方式: 示例代码(在laf.jar中编译和打包): 场景1以普通用户身份登录计算机(在GUI模式下) 样本输出(作为用户) 样本输出(通过su切换到root) 场景2以root用户身份登录到计算机(在GUI模式下) 样本输出(作为根) 场景3以普通用户身份通过SSH登录到机器(与上面的场景1类似,但在本例中为相同的LAF) 样本输出(作为用户) 样本输

我注意到Java为根用户和非根用户提供了不同的外观类。我试图理解如何使LAF保持一致。此外,即使在用户/根目录中也不一致:取决于用户/根目录的登录方式:

示例代码(在
laf.jar
中编译和打包):

场景1以普通用户身份登录计算机(在GUI模式下)

样本输出(作为用户)

样本输出(通过
su
切换到root

场景2以root用户身份登录到计算机(在GUI模式下)

样本输出(作为根)

场景3以普通用户身份通过SSH登录到机器(与上面的场景1类似,但在本例中为相同的LAF)

样本输出(作为用户)

样本输出(切换到根目录)

软件版本:

[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)

getSystemLookAndFeelClassName
的第一行是:

public static String getSystemLookAndFeelClassName() {
    String systemLAF = AccessController.doPrivileged(
                         new GetPropertyAction("swing.systemlaf"));
因此,您可以使用用户的JAVA_选项来设置

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

默认情况下

将其添加到用户的
.rc
-文件中:

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

关于

这与根有关,而与环境变量有关

基本上,该方法的工作原理如下:

  • 检查
    swing.systemlaf
    system属性。这允许用户覆盖系统想要选择的任何内容。如果它不为null,则使用它
  • 否则,如果操作系统是Windows,则返回
    WindowsLookAndFeel
  • 否则,它将检查
    sun.desktop
    属性。如果
    sun.desktop
    设置为
    gnome
    ,并且GTK本机可用,则它将返回
    GTKLookAndFeel
  • 否则,检查Mac OS X和Solaris,并为这些操作系统返回适当的值
  • 如果所有其他检查均失败,则返回“跨平台”L&F,即
    MetalLookAndFeel
因此,与Linux/Unix相关的部分是检查
sun.desktop
的部分。此属性在JVM启动时设置。如果环境变量
gnome\u DESKTOP\u SESSION\u ID
存在,则将其设置为
gnome
,忽略其内容,否则将其设置为null。我相信是这样的

因此,在Linux上,如果设置了该环境变量(并且GTK可用),则L&F将设置为
GTKLookAndFeel
。否则,它将被设置为
MetalLookAndFeel

当您使用桌面管理器登录到基于Gnome的Linux时,您的环境将设置该变量。但是默认情况下,
su
命令不会传播环境变量。因此,当您向任何用户su时,不一定是root用户,您将丢失
GNOME\u DESKTOP\u SESSION\u ID
环境变量,Java将默认为
MetalLookAndFeel

您可以使用
su-p
使您的环境通过
su
,或者如果您使用的是
sudo
,则使用
sudo-E

ssh
命令与
su
sudo
一样,不会传播环境变量。这也可以使用
~/.ssh/environment
解决


但是,如前所述,通过将
-Dswing.systemlaf=…
开关传递到java命令,您可以轻松地强制执行特定的L&F。

这可能来自用户环境的差异;在不同的场景中尝试查看
env
的结果,或者在Java中,使用
System.getenv()
的结果。您是否可以在各种设置中检查您的环境中是否有变量
GNOME\u DESKTOP\u SESSION\u ID
?1)正如用户所说的“这是无摩擦的”2)在“su-”作为root用户,它提供了空白输出如果您想要一致的跨平台外观,您可能希望坚持使用or
UIManager.getCrossPlatformLookAndFeelClassName()
。Nimbus创建为一个外观更好的跨平台L&F,但由于任何原因,从未更新为默认值。当然,我将尝试使用属性,但我感到惊讶的是,它不是开箱即用的。在用户级别(bashrc或profile)修改不是一个选项,因为我们不控制它,也不希望我们的应用程序影响系统。所以,我的解决方案是在应用程序的启动脚本中添加一个片段“-Dswing.systemlaf=javax.swing.plaf.metal.MetalLookAndFeel”记录com.sun.javax.swing.plaf.metal.CrossPlatformLookAndFeel在我使用的IBM JRE中不可用。所以这不是一个跨平台的解决方案。我仍然建议使用我在前面的评论中提到的内容:javax.swing.plaf.metal.MetallookandFeelTanks进行解释,正如我在上面所说,GNOME_DESKTOP_SESSION_ID没有包含任何有意义的内容。我的选择是通过-DBTW显式定义LAF,在Ubuntu OS 12.04.02上也观察到了这个问题。令人惊讶的是,在Ubuntu上,我得到了完全相同的结果:作为用户,它说echo-echo$GNOME\u DESKTOP\u SESSION\u ID=>“这是去擦亮的”,作为根空输出,以及作为用户和根的不同LAF。@BaratSahdzijeu它不必包含任何有意义的内容。它的存在只是为了选择GTK L&F。是的,Ubuntu是基于Gnome的Linux。这有助于解释问题,但没有提供一个与桌面行为相匹配的可伸缩解决方案。例如,如果安装程序希望在安装后在用户空间中启动Java进程,如何获得用户的环境变量而不强制用户提供在安装程序中调用的
sudo
命令的开关?对于一个特定的安装程序,
sudo-u
命令用于在用户空间启动进程,因此环境变量被
sudo
隐藏两次。安装程序如何适应这种情况?任何人如何在Ope中找到任何东西
[root@yyy Downloads]# java -classpath ./laf.jar laf
com.sun.java.swing.plaf.gtk.GTKLookAndFeel
[xxx@yyy Downloads]$ java -classpath laf.jar laf
javax.swing.plaf.metal.MetalLookAndFeel
[root@yyy Downloads]# java -classpath ./laf.jar laf
javax.swing.plaf.metal.MetalLookAndFeel
[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)
public static String getSystemLookAndFeelClassName() {
    String systemLAF = AccessController.doPrivileged(
                         new GetPropertyAction("swing.systemlaf"));
set JAVA_OPTS=-Dswing.systemlaf=javax.swing.plaf.metal.MetalLookAndFeel
export JAVA_OPTS