改变特定窗口的外观 [英] Changing look and feel of specific window

查看:85
本文介绍了改变特定窗口的外观的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为更大的GUI应用程序编写脚本。主应用程序窗口使用系统的 LookAndFeel ,但我希望我的脚本的GUI使用Nimbus LookAndFeel 。创建GUI后,我想将 LookAndFeel 设置回原始版本。我觉得以下 SSCCE 应该有效,但我得到的是 NullPointerException 使用我的组件对象时。

I'm writing a script for a larger GUI application. The main application window uses the system's LookAndFeel, but I want my script's GUI to use the Nimbus LookAndFeel. After GUI creation, I want to set the LookAndFeel back to the original. I feel the below SSCCE should work, but I'm getting a NullPointerException when using my Component objects.

import java.awt.Dimension;
import java.awt.GridBagLayout;
import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;

public class GUI extends JFrame {
    private static LookAndFeel originalLookAndFeel = UIManager.getLookAndFeel();
    static {
        System.out.println("At start, look and feel is " + UIManager.getLookAndFeel().getName());
        try {
            setNimbusLookAndFeel();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        System.out.println("Look and feel changed to " + UIManager.getLookAndFeel().getName()
                + " before component creation");
    }
    private GridBagLayout gridBag = new GridBagLayout();
    private JTabbedPane tabs = new JTabbedPane();
    private JPanel selectionPanel = new JPanel(gridBag);
    private JPanel infoPanel = new JPanel(gridBag);
    private JPanel settingsPanel = new JPanel(gridBag);

    public GUI() {
        setWindowProperties();
        setUpComponents();
        addComponents();

        try {
            System.out.println("Setting to original, which is " + originalLookAndFeel.getName());
            UIManager.setLookAndFeel(originalLookAndFeel);
            System.out.println("Current look and feel is " + UIManager.getLookAndFeel().getName());
        } catch (UnsupportedLookAndFeelException e) {
            e.printStackTrace();
        }
    }

    private void setWindowProperties() {
        setLayout(gridBag);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(new Dimension(700, 600));
        setTitle("fAmos Quester");
        setResizable(false);
        setLocationRelativeTo(null);
    }

    private static void setNimbusLookAndFeel() {
        try {
            for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    UIManager.setLookAndFeel(info.getClassName());
                }
            }
        } catch (Exception e) {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (Exception e2) {
            }
        }
    }

    public void setUpComponents() {
        tabs.addTab("Quest selection", selectionPanel);
        tabs.addTab("Quest info", infoPanel);
        tabs.addTab("Settings", settingsPanel);

        selectionPanel.setPreferredSize(new Dimension(650, 500));
        infoPanel.setPreferredSize(new Dimension(650, 500));
        settingsPanel.setPreferredSize(new Dimension(650, 500));
    }

    private void addComponents() {
        add(tabs);
    }

    public static void main(String[] args) {
        new GUI().setVisible(true);
    }
}


推荐答案

As一般来说,混合LAF并不是一个好主意。这个问题就是原因的一个例子。

As a general rule it is not a good idea to mix LAF's. This problem is an example of why.

Nimbus LAF中有些东西可能不允许你这样做。按原样运行代码。它会将LAF设置为系统LAF ,然后重置LAF。在我的情况下,系统是Windows,它似乎工作正常。然后更改代码以使用Nimbus LAF。它似乎最初工作,但尝试调整框架大小,你会得到错误。因此,看起来Nimbus帧不能完全独立于当前的LAF。

There is something in the Nimbus LAF that may not allow you to do this. Run the code as is. It will set the LAF to the System LAF and then reset the LAF. In my case the system is Windows and it appear to work fine. Then change the code to use the Nimbus LAF. It appears to work initially, but try resizing the frame and you get the errors. So it would appear that the Nimbus frame does not work completely independent of the current LAF.

import java.awt.*;
import java.awt.event.*;
import java.awt.GridBagLayout;
import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;

public class GUI2 extends JFrame {
    private static LookAndFeel originalLookAndFeel = UIManager.getLookAndFeel();
/*
    private GridBagLayout gridBag = new GridBagLayout();
    private JTabbedPane tabs = new JTabbedPane();
    private JPanel selectionPanel = new JPanel(gridBag);
    private JPanel infoPanel = new JPanel(gridBag);
    private JPanel settingsPanel = new JPanel(gridBag);
*/
    private GridBagLayout gridBag;
    private JTabbedPane tabs;
    private JPanel selectionPanel;
    private JPanel infoPanel;
    private JPanel settingsPanel;

    public GUI2() {
        System.out.println("At start, look and feel is " + UIManager.getLookAndFeel().getName());
        try {
//            setNimbusLookAndFeel();
          UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("Look and feel changed to " + UIManager.getLookAndFeel().getName()
                + " before component creation");

        gridBag = new GridBagLayout();
        setLayout(gridBag);
        tabs = new JTabbedPane();
        selectionPanel = new JPanel(gridBag);
        infoPanel = new JPanel(gridBag);
        settingsPanel = new JPanel(gridBag);

        setUpComponents();
        addComponents();
        setWindowProperties();

        Action reset = new AbstractAction()
        {
            public void actionPerformed(ActionEvent ae)
            {
                try {
                    System.out.println("Setting to original, which is " + originalLookAndFeel.getName());
                    UIManager.setLookAndFeel(originalLookAndFeel);
                    System.out.println("Current look and feel is " + UIManager.getLookAndFeel().getName());
                } catch (UnsupportedLookAndFeelException e) {
                    //e.printStackTrace();
                    System.out.println(e.getMessage());
                }

            }
        };

        Timer timer = new Timer(500, reset);
        timer.setRepeats(false);
        timer.start();
    }

    private void setWindowProperties() {
//        setLayout(gridBag);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("fAmos Quester");
//        setResizable(false);
        pack();
        setLocationRelativeTo(null);
    }

    private void setNimbusLookAndFeel() {
        try {
            for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    UIManager.setLookAndFeel(info.getClassName());
                }
            }
        } catch (Exception e) {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (Exception e2) {
            }
        }
    }

    public void setUpComponents() {
        tabs.addTab("Quest selection", selectionPanel);
        tabs.addTab("Quest info", infoPanel);
        tabs.addTab("Settings", settingsPanel);

        selectionPanel.setPreferredSize(new Dimension(650, 500));
        infoPanel.setPreferredSize(new Dimension(650, 500));
        settingsPanel.setPreferredSize(new Dimension(650, 500));
    }

    private void addComponents() {
        add(tabs);
    }

    public static void main(String[] args) {
        new GUI2().setVisible(true);
    }
}

也许解决方案是使用以下方法创建组件Nimbus LAF如上所述。但是,在取消激活帧之前,请勿重置LAF。然后,您可以尝试在每次激活帧时重置LAF。您可以使用WindowListener来处理激活/停用的事件。

Maybe a solution would be to create the component using the Nimbus LAF as is done above. However, don't reset the LAF until the frame is deactivated. Then you could try resetting the LAF every time the frame is activated. You would use a WindowListener to handle the activated/deactivated events.

这篇关于改变特定窗口的外观的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆