改变特定窗口的外观

Joe*_*hel 3 java swing nullpointerexception look-and-feel

我正在为更大的GUI应用程序编写脚本.主应用程序窗口使用系统LookAndFeel,但我希望我的脚本的GUI使用Nimbus LookAndFeel.创建GUI后,我想将其设置LookAndFeel回原始版本.我觉得下面的SSCCE应该可以工作,但我NullPointerException在使用我的Component对象时会得到一个.

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

cam*_*ckr 5

作为一般规则,混合LAF并不是一个好主意.这个问题就是一个例子.

Nimbus LAF中有一些东西可能不允许你这样做.按原样运行代码.它会将LAF设置为System LAF然后重置LAF.在我的情况下,系统是Windows,它似乎工作正常.然后更改代码以使用Nimbus LAF.它似乎最初工作,但尝试调整框架大小,你会得到错误.因此,看起来Nimbus帧不能完全独立于当前的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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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