如何在KDE上强制/使用GTKLookAndFeel的Java界面?

5
首先,使用GNOME不是一个选项(但可以安装其库)。
我需要知道如何在当前安装的KDE外观下显示Java Swing桌面应用程序所需的内容。理想情况下,解决方案应该允许我应用与底层窗口系统相似的外观(例如:Windows LNF适用于Windows,GTK LNF适用于Gnome(GTK),QT LNF适用于KDE(QT),其他平台的默认LNF)。
在KDE下,您可以配置它使用当前KDE主题来为GTK应用程序提供服务。因此,如果该解决方案适用于GTK,则可以使用。
当我在Gnome(Ubuntu 8.04)下运行以下代码时,Java应用程序看起来很漂亮。它与其他应用程序完美地集成在一起。
try {
  // Set System L&F
  UIManager.setLookAndFeel(
  UIManager.getSystemLookAndFeelClassName());
} catch(Exception e) { //Handle it }

然而,如果我在带有KDE的Debian(Lenny)下运行相同的东西,则UIManager.getSystemLookAndFeelClassName()调用返回Java默认值。 如果我继续强制使用GTK LNF,应用程序将无法正常工作。一些字段变得不可见,其他字段变得位置不当,所有内容都无法使用:

try {
  //Force the GTK LNF on top of KDE, but **it doesn't work**
  UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
} catch (Exception e) { /*Handle it*/ }

我也试过放置以下代码。它让用户选择可用的任意LNF,然后尝试设置它。Metal和Motif工作正常。GTK不行。滑块非常混乱。列表框看起来很丑并消失了,但似乎可用。按钮和菜单看起来还好。相关代码如下:

(...)
    /** Creates new form SwingFrame */
    public SwingFrame() {

    initComponents();

    //Save all available lafs in a combobox
    cbLafs.removeAllItems();
    UIManager.LookAndFeelInfo[] lafs=UIManager.getInstalledLookAndFeels();

    for (int i=0,t=lafs.length;i<t;i++)
    {
        cbLafs.addItem(lafs[i]);
        System.out.println(lafs[i].getName());
    }

    }

public void changeLookAndFeel(String laf)
{
    //If not specified, get the default one
    if (laf==null) {
    laf=UIManager.getSystemLookAndFeelClassName();
    }

        try {
        // Set System L&F
        UIManager.setLookAndFeel(laf);
    }
    catch (Exception e) {
       // handle exception
        e.printStackTrace();
    }
    SwingUtilities.updateComponentTreeUI(this);

}

   private void cbLafsActionPerformed(java.awt.event.ActionEvent evt) {                                       
        // TODO add your handling code here:
        UIManager.LookAndFeelInfo laf=(UIManager.LookAndFeelInfo)cbLafs.getSelectedItem();
        if (laf==null)
            changeLookAndFeel(null);
        else
            changeLookAndFeel(laf.getClassName());
    }                                     

同样的系统下,所有基于GTK的应用程序(例如:Firefox)都可以正常工作。所以:
1)在KDE环境下,缺少什么条件才能让Java GTK LNF应用程序正常工作?
2)JVM检查哪些内容来将GTK作为默认的系统主题?
感谢您的帮助。 Luis Fernando
注:我已经尝试了其他解决方案,比如JGoodies、纯AWT和SWT。然而,Swing与GTK LNF是最好的解决方案,因为它避免了SWT本地库和JGoodies额外的jar文件的麻烦(此外,在Gnome下,JGoodies LNF看起来没有Swing GTK那么集成)。AWT看起来很难看(像motif),并且缺少很多功能。
4个回答

2
您可以通过命令行设置外观和感觉:
java -Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel MyApp 此外,SwingSet2.jnlp提供了一个演示所有可更改内容的样本演示。源代码和其他信息可以在这里找到:链接文本

即使是SwingSet2也无法工作!滑块和组合框都坏了...但它们在gnome下可以工作。这是一个bug还是缺少某些gtk库? - Luis Soeiro
我敢打赌,如果SwingSet2不起作用,那么肯定是有bug或者缺少某些东西。 - Joshua

1

引用文档:

  1. 如果系统属性 swing.defaultlaf 非空,则使用其值作为默认的外观类名。

  2. 如果存在 Properties 文件 swing.properties 并且包含键 swing.defaultlaf,则使用其值作为默认的外观类名。检查 swing.properties 的位置可能因 Java 平台实现而异。在 Sun 的实现中,位置为 ${java.home}/lib/swing.properties

有关更多详细信息,请参阅所使用实现的发行说明。

但我99%确定你的问题是这个(再次引用文档):

更改外观后,必须在所有JComponents上调用updateUI。方法SwingUtilities.updateComponentTreeUI(java.awt.Component)使得将updateUI应用于容器层次结构变得容易。有关详细信息,请参阅它。不在更改外观后调用updateUI的确切行为未指定。很可能会收到意外异常、绘图问题或更糟的情况。
如果您不想在所有JComponents上调用updateUI,请确保在每个其他swing代码之前调用UIManager.setLookAndFeel。

好的。我正在基础框架上使用updateUI,希望它能更新整个树形结构。然而,控件仍然混乱不堪。 - Luis Soeiro

1

或许这个可以运行:

try {
// sure look and feel
UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
// not-so-sure look and feel
System.setProperty("os.name", "Windows");
System.setProperty("os.version", "5.1");
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} 
catch (Exception ex) {
ex.printStackTrace();
}

嗨,我已经尝试了第一个选项。不知何故,所有小部件都变得非常混乱(大小错误,缺少项目,点击位置错误,有些甚至根本没有显示)...在Java之外,所有GTK应用程序都能正常工作,并且还使用当前的KDE主题。我只能让这段代码在Ubuntu(Gnome)上运行。 - Luis Soeiro
谢谢,对我有用 -- 不过在Swing中使用GTK甚至比默认的Swing还要丑。难以置信;-/。 - greenoldman

-1

GTK Laf 在我看来,就是坏的。它不遵守一些随机的设置。我相信它不应该在大多数组件上遵守 setBackground()、setForeground() 或 setFont()。

如果你使用的是 java >1.4.2,我建议使用 MetalLookAndFeel [应该是 UIManager.getCrossPlatformLookAndFeelClassName()]。如果你使用的是 >1.6.0_u10,你可以尝试 NautilusLookAndFeel。我个人觉得 Metal 看起来更好看。


我同意。当使用GTK 3时,GTK2的外观可能会很丑,但这可能更适合作为评论。另外,我想偷偷地给出一个小提示:如果你想从命令行强制应用程序使用Metal,可以添加-Dsun.desktop=none(适用于Java 8,但不适用于更新版本)。 - TheKodeToad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接